Is it possible to do a "union" of a protected variable from a parent class? I would do a template but it makes it impossible to use as a pointer. So I was wondering if it was possible to do something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class Parent {
protected:
void* data;
public:
Parent(char* file); // load file is the same no matter what class, place pointer into data
};
class StrChild : public Parent {
union { char* str; void* data };
};
class IntChild : public Parent {
union { int* i; void* data; };
};
Rather than defining "char* str = data;" in every function I write for the child class and not defining a separate variable.
Is it possible to do a "union" of a protected variable from a parent class?
No, if you declare data in any of its derived classes, then that data will override the data in the parent. And if you have a data as part of a union in a derived class, then that data will be a different data than the one in the parent.
I would do a template but it makes it impossible to use as a pointer.
template<class T>
class Parent {
protected:
T* data;
};
class Child : Parent<int> {
};
class AnotherChild : Parent<char> {
};
The problem with this though is it defeats the purpose of having a base class:
1 2 3 4
Parent<void>* array[100];
array[0] = new Child(); // error no type conversion Parent<int> to Parent<void>
array[1] = new AnotherChild(); // error no conversion Parent<char> to Parent<void>
Or passing it as a parameter as a function.
1 2 3 4 5 6 7
void foo( Parent<void>* ){
// do something
}
foo( new Child() ); // error no conversion
That's the thing though, there isn't going to be a lot of specialization which is why there is a base class. I have several functions which are defined in my base class and most of them revolve around the data variable so I would rather it be defined in the base class.
The parent class shouldn't care what data type it is, the only reason I would like it to be known is for the children, so I don't need to type redundant code such as MyClass* c = (MyClass*)data;. So I do not really need templating in this case and I was wondering if there's a better solution than defining a variable each time I need to use it.
Well, a pointer's a pointer so once you've assigned it, they're pointing to the same thing.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
class Parent {
protected:
void* data;
};
class ChildChar : public Parent {
protected:
char* charData;
public:
ChildChar(char* file) : Parent(file)
{
//pointer assignment, now charData will point to whatever
//data points to even when changes happen in the base class
charData = static_cast<char*>(data);
}
};
Perhaps the solution can be as simple as that.
EDIT: Unless of course the pointer gets reassigned in the base class. In which case, you can define a virtual Reassign method that the derived classes override and that's called by the base class whenever the pointer ever gets reassigned. (Or, you could reassign the pointer whenever you want to use it :)
EDIT2: Alright, this will work and you won't have to worry about data being reassigned in the base class:
1 2 3 4 5 6 7 8 9 10 11 12
class ChildChar : public Parent {
protected:
char** charData;
public:
ChildChar(char* file) : Parent(file)
{
//now charData will point to data, so we won't have
//to care if data gets reassigned
charData = static_cast<char**>(&data);
}
};
I believe it will also work if you make it so the derived class has a reference to data, i.e. if you did char*& charData instead.