473,396 Members | 1,722 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

ABC w/o virtual functions?

Let's say I want to have an abstract base class define a method which
all the subclasses will implement.

However, I cannot use virtual methods (long story short: these objects
are only 24 bytes and I have several million of them).

Is it possible for me to define the method in the ABC interface without
virtuals?
As I said, all the subclasses will provide the method.

Thanks,

Joseph

Feb 9 '06 #1
18 1643

Joseph Turian wrote:
Let's say I want to have an abstract base class define a method which
all the subclasses will implement.

However, I cannot use virtual methods (long story short: these objects
are only 24 bytes and I have several million of them).

Is it possible for me to define the method in the ABC interface without
virtuals?
As I said, all the subclasses will provide the method.


An abstract function cannot be virtual so there is one strike against
you.

If you don't define the function virtual the subclass functions will
not be called if you are calling through the parent's pointer.

If you can tell at compile time what is being done and with who you can
use templates but this breaks down if you want runtime and it also
breaks down if you are calling with the parent pointer/reference.

In short, the only way to provide polymorphic behavior is to use
virtual functions. You can pass these objects off as their parent but
that is what they will behave like while being passed off as such.

I think you need to look more closely at your problem space and see if
your solution could be better.

Feb 9 '06 #2
"Joseph Turian" <tu****@gmail.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
Let's say I want to have an abstract base class define a method which
all the subclasses will implement.

However, I cannot use virtual methods (long story short: these objects
are only 24 bytes and I have several million of them).

Is it possible for me to define the method in the ABC interface without
virtuals?
As I said, all the subclasses will provide the method.

Thanks,

Joseph


If the method is virtual or not should not increase the derived class size
at all. Go ahead and try it. Methods themselves generally do not increase
the size of an instance, although a derived class has to be larger than a
base class. In other words, try sizeof of your base and yoru derived, make
it virtual, then try it again.
Feb 9 '06 #3

roberts.n...@gmail.com wrote:
Joseph Turian wrote:
Let's say I want to have an abstract base class define a method which
all the subclasses will implement.

However, I cannot use virtual methods (long story short: these objects
are only 24 bytes and I have several million of them).

Is it possible for me to define the method in the ABC interface without
virtuals?
As I said, all the subclasses will provide the method.


An abstract function cannot be virtual so there is one strike against
you.


I meant the exact opposite of course....abstract functions MUST be
virtual and cannot be otherwise.

Feb 9 '06 #4
GB
Jim Langston wrote:
If the method is virtual or not should not increase the derived class size
at all.


That is typically only true if there were already other virtual members.
If there are no virtual members, making one of them virtual will
typically increase the size of objects of this class by the size of a
pointer, which will point to the v-table for the class. This is
implementation-dependent, but that is how it usually works.

Gregg
Feb 9 '06 #5
* Joseph Turian:
Let's say I want to have an abstract base class define a method which
all the subclasses will implement.

However, I cannot use virtual methods (long story short: these objects
are only 24 bytes and I have several million of them).

Is it possible for me to define the method in the ABC interface without
virtuals?
As I said, all the subclasses will provide the method.


You need at least 1 (that's one) byte per object to identify the derived
class of an object.

If you use virtual functions you'll probably use 4 bytes, unless this is
64-bit, in which case you'll probably use 8 bytes, again, per object.

To make do with just 1 byte type info per object you're limiting the
number of derived classes to 256.

The following (not designed or sanity-checked or refactored, just
typed-in-a-hurry) code shows one idea.

I'm sure you can up with techniques to abstract upwards all that
horrendous boilerplate code in each derived class.
#include <iostream>
#include <ostream>

#include <string>
#include <vector>

typedef unsigned char Byte;

class Base
{
public:
typedef std::string (*PseudoVirtualNameFunc)( Base const& );

protected:
Byte myClassId;

protected:
static std::vector<PseudoVirtualNameFunc> pvnFuncs;

Byte install( PseudoVirtualNameFunc aFunc )
{
pvnFuncs.push_back( aFunc );
return static_cast<Byte>( pvnFuncs.size() - 1 );
}

public:
std::string pseudoVirtualName() const
{
return (*pvnFuncs.at( myClassId ))( *this );
}
};

std::vector<Base::PseudoVirtualNameFunc> Base::pvnFuncs;
class Foo: public Base
{
private:
char myObjectId;

protected:
static std::string pseudoVirtualNameForwarder( Base const& self )
{
return static_cast<Foo const&>( self ).pseudoVirtualName();
}

public:
Foo( char objectId ): myObjectId( objectId )
{
static bool isFirstInstance = true;
static Byte theFooClassId;

if( isFirstInstance )
{
theFooClassId = install( &Foo::pseudoVirtualNameForwarder );
isFirstInstance = false;
}
myClassId = theFooClassId;
}

std::string pseudoVirtualName() const
{
return std::string() + "Foo with object id " + myObjectId;
}
};

int main()
{
Foo const obj( 'X' );
Base const& ref = obj;

std::cout << ref.pseudoVirtualName() << std::endl;
std::cout << "Size of Foo is " << sizeof( Foo ) << " bytes." <<
std::endl;
}
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 9 '06 #6
On 8 Feb 2006 22:29:04 -0800, "Joseph Turian" <tu****@gmail.com>
wrote:
Let's say I want to have an abstract base class define a method which
all the subclasses will implement.

However, I cannot use virtual methods (long story short: these objects
are only 24 bytes and I have several million of them).

Is it possible for me to define the method in the ABC interface without
virtuals?
As I said, all the subclasses will provide the method.

Thanks,

Joseph


The solution may be using templates. It will grow your code but not
your data,should be adequate if you use millions of objects but *not*
if you need them all to derive from the same base class and be called
through that base class.

Zara
Feb 9 '06 #7

"Joseph Turian" <tu****@gmail.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
Let's say I want to have an abstract base class define a method which
all the subclasses will implement.

However, I cannot use virtual methods (long story short: these objects
are only 24 bytes and I have several million of them).


You cannot do what you want without adding some data.

It generally depends on the implementation of your compiler, but
in most cases adding virtual methods to a base doesn't increase
the size of the derivants, if _they_ already have virtual methods
anyway. If none of your classes have virtual methods, then you
probably can't escape using some memory.

If you insist on _not_ using virtual methods, you can add a data
member in your ABC, type of which is function pointer. In the
ABC, add a constructor that takes a function pointer and declare
it as protected. Implement the "polymorphic" method so that it
just passes its arguments to the function pointed to by the pointer.
Derived classes will subsequently call the base class constructor
with an argument that points to their implementation of the method.

- Risto -

Simple example follows (syntax errors left as an exercise :-) :

struct Base
{
void (*f)();
Base( void (*p)() ) : f(p) { }
void DoVirtual( void ) { f(); }
};

struct Bird : public Base
{
static void DoBird() { cout << "Quack! Quack!" << endl; }
Bird() : Base(DoBird) { }
};

struct Fish : public Base
{
static void DoFish() { cout << "<blub> <blub>" << endl; }
Fish() : Base(DoFish) { }
};

int main()
{
Bird donald;
Fish nemo;

donald.DoVirtual(); // Quack! Quack!
nemo.DoVirtual(); // <blub> <blub>

return 0;
};
Feb 9 '06 #8
Actually. I think You can get away from the 1byte requirement by
setting up
the function table with typeid([derivedclass]), as key.

But this is probably the best way to do it.

Feb 9 '06 #9
Sorry about missing quote..
Above is ment as a reply to Alfs post:
You need at least 1 (that's one) byte per object to identify the derived class of an object.
If you use virtual functions you'll probably use 4 bytes, unless this is 64-bit, in which case you'll probably use 8 bytes, again, per object.

To make do with just 1 byte type info per object you're limiting the number of derived classes to 256.

The following (not designed or sanity-checked or refactored, just typed-in-a-hurry) code shows one idea.

I'm sure you can up with techniques to abstract upwards all that

horrendous boilerplate code in each derived class.

Feb 9 '06 #10
* je****@alphacash.se:
Actually. I think You can get away from the 1byte requirement by
setting up the function table with typeid([derivedclass]), as key.


Chicken and egg. There's no magic. "typeid" relies on the class being
polymorphic...

However, one could get away from the 1 byte per object requirement by
using custom allocation so that the type of object could be inferred
from the object's address.

But that would be the proverbial fly massacre by H-bomb, I think.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Feb 9 '06 #11
typeid requires a polymorphic class?? typeid(int) works.
Now there seems to be something I dont know.
Enlighten me please.

pseudocode:
map<typeid,function> functionmap;

baseclass::baseclass()
{
}

derivedclass::derivedclass()
{
functionmap[typeid(this)]=function_to_map;
}
// end pseudo code
You say above would require baseclass to be polymorphic, yet
typeid([int,float,char]) works fine?
Please explain.
/Jesper
PS. who do you quote a post? DS

Feb 9 '06 #12

je****@alphacash.se wrote:
PS. who do you quote a post? DS


Assuming you meant "how" rather than "who", from Google Groups you need
to ignore the "Reply" button at the bottom of the message. Instead
click "Show options" at the top of the message and use the "Reply"
button there.

Gavin Deane

Feb 9 '06 #13
Ahh :-)
Thank you.
/Jesper
Gavin Deane wrote:
je****@alphacash.se wrote:
PS. who do you quote a post? DS


Assuming you meant "how" rather than "who", from Google Groups you need
to ignore the "Reply" button at the bottom of the message. Instead
click "Show options" at the top of the message and use the "Reply"
button there.

Gavin Deane


Feb 9 '06 #14
Doh!
I'm stupid. Sorry..
Accessing the right function would be a little less easy :-)

(would brute force dynamic_cast allow for it to work? And if so, would
it be a
plausible solution? How much would the performance suffer?)
/Jesper

Alf P. Steinbach wrote:
* je****@alphacash.se:
Actually. I think You can get away from the 1byte requirement by
setting up the function table with typeid([derivedclass]), as key.


Chicken and egg. There's no magic. "typeid" relies on the class being
polymorphic...

However, one could get away from the 1 byte per object requirement by
using custom allocation so that the type of object could be inferred
from the object's address.

But that would be the proverbial fly massacre by H-bomb, I think.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


Feb 9 '06 #15
* je****@alphacash.se:
[top-posting, quoting signature]
Using Google's quoting facilities isn't easy! But please,
don't top-post, and don't quote signatures and other extranous
stuff. Corrected.

* je****@alphacash.se: * Alf P. Steinbach:
* je****@alphacash.se:

Actually. I think You can get away from the 1byte requirement by
setting up the function table with typeid([derivedclass]), as key.
Chicken and egg. There's no magic. "typeid" relies on the class being
polymorphic...

However, one could get away from the 1 byte per object requirement by
using custom allocation so that the type of object could be inferred
from the object's address.

But that would be the proverbial fly massacre by H-bomb, I think.


Doh!
I'm stupid. Sorry..
Accessing the right function would be a little less easy :-)


It would be impossible. When all you have is a pointer or reference
to a non-polymorphic Base object, typeid or dynamic_cast doesn't tell
you which dynamic type it is.

(would brute force dynamic_cast allow for it to work?


Nope.
Cheers,

- Alf
Feb 9 '06 #16
ro**********@gmail.com wrote:
roberts.n...@gmail.com wrote:
Joseph Turian wrote:
Let's say I want to have an abstract base class define a method which
all the subclasses will implement.

However, I cannot use virtual methods (long story short: these objects
are only 24 bytes and I have several million of them).

Is it possible for me to define the method in the ABC interface without
virtuals?
As I said, all the subclasses will provide the method.


An abstract function cannot be virtual so there is one strike against
you.

I meant the exact opposite of course....abstract functions MUST be
virtual and cannot be otherwise.


There is no such concept in C++ as "abstract function". Just so there
is no confusion in the future...

V
--
Please remove capital As from my address when replying by mail
Feb 9 '06 #17

Zara wrote:
The solution may be using templates. It will grow your code but not
your data,should be adequate if you use millions of objects but *not*
if you need them all to derive from the same base class and be called
through that base class.


Could you please explain how to do this using templates?

Thanks,

Joseph

Feb 10 '06 #18
je****@alphacash.se wrote:
typeid requires a polymorphic class?? typeid(int) works.
Now there seems to be something I dont know.


It requires a polymorphic class if you need RTTI.
typeid(int) is statically determined, but typeid(*ptrToBase) isn't.

HTH,
Michiel Salters

Feb 10 '06 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: vijay | last post by:
I have a doubt with size of classed with virtual functions I have declared A,A1,A2 ,B , C, D some classes with no varaibles but a vitual function each, The size of A is as expected 4 bytes with...
5
by: Ryan Faulkner | last post by:
Hi, Im having a few problems with virtual functions (Im using the Visual C++ environment by the way). I have a base class with three virtual functions and a derived class with a single new...
18
by: nenad | last post by:
Wouldn't it be nice if we could do something like this: class Funky{ public: auto virtual void doStuff(){ // dostuff } };
19
by: qazmlp | last post by:
class base { // other members public: virtual ~base() { } virtual void virtualMethod1()=0 ; virtual void virtualMethod2()=0 ; virtual void virtualMethod3()=0 ;
7
by: Aguilar, James | last post by:
I've heard that virtual functions are relatively ineffecient, especially virtual functions that are small but get called very frequently. Could someone describe for me the process by which the...
25
by: Stijn Oude Brunink | last post by:
Hello, I have the following trade off to make: A base class with 2 virtual functions would be realy helpfull for the problem I'm working on. Still though the functions that my program will use...
11
by: santosh | last post by:
Hello, I was going through the Marshal Cline's C++ FAQ-Lite. I have a doubt regarding section 33.10. Here he is declaring a pure virtual destructor in the base class. And again defining...
7
by: ashishnh33 | last post by:
i want to know about the concept behind the virtual functions.
5
by: Dilip | last post by:
In a polymorphic hierarchy is it common practice to have public virtual functions in the base class with a default empty implementation and let the derived classes decide whether they want to...
14
by: v4vijayakumar | last post by:
Why we need "virtual private member functions"? Why it is not an (compile time) error?
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.