Daniel Graifer said:
Why doesn't c++ support virtual data? It supports class data of type
pointer to function (that's what virtual functions really are). In
terms of implementation, why can't I have other types of data in my vtable?
RTTI could be implemented this way instead of as a special case for the
compiler. It would also be useful for class specific memory management
implementations.
"Why" something is done (in the standard) probably isn't best discussed
here. But, here goes anyway...
I can't imagine where I would need to use "virtual data". Member data has a
type, and a size associated with it. If a descendant class uses the same
type of data for a member variable of the same name, then there's no need
for it to be virtual. If, however, that variable is to be of a different
type in the descendant class, then any use of the variable (i.e., any code
in a function) needs to support that different type. Then what? You end up
writing virtual functions to handle the virtual data anyway, so why use the
same variable? Why not just use a different variable, introduced in the
derived class? Or a pointer to another object (see discussion further
down)?
For example, say your base class uses the member variable x, declared as an
int. But your derived class needs a more complicated variable x, say of
type MyXClass. Now, you call a function in the class hierarchy, and that
function needs to operate on that member x. So you call some member
function ModifyX(). But that function has to be virtual, so that the
derived class can modify x as a MyXClass object and not as an int. So what
have you gained?
You can't pass the "virtual" x anywhere, because it has no known type (until
it is actually called), so no parameter list can be constructed that will
satisfy both the base class and the derived class.
If you need virtual "behavior" of a member, then make that member a pointer
to a base class object, and have your derived class create a derived-class
instance whereas your base class creates it as an instance of the base class
instance. Like this:
class BaseMember
{
int x;
BaseMember( const int initX ) : x(initX) {};
virtual ~BaseMember() {};
};
class DerivedMember : public BaseMember
{
DerivedMember( const int initX ) : BaseMember(x) {};
};
class BaseClass
{
BaseMember* p_x;
BaseClass() : x(NULL);
virtual Init( const int initX );
virtual ~BaseClass();
};
class DerivedClass : public BaseClass
{
virtual Init( const int initX );
};
BaseClass::Init()
{
p_x = new BaseMember();
}
BaseClass::~BaseClass()
{
delete p_x;
}
DerivedClass::Init( const int initX )
{
p_x = new DerivedMember( initX );
}
(And, don't forget to add appropriate assignment operator and copy
constructors! I've left them out here.)
Now, p_x is a pointer to a data type which is, in effect, virtual. When you
make calls to its memebrs, they are handled by the virtual behavior of its
functions. You don't need to use the vtable for the data, because the
vtable (or whatever method is used to provide virtual behavior) is handled
in the method calling.
Will this work for you?
-Howard