* 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?