I'm new to c++ (but I know other languages) and I'm confused about how to implement something. I hope one of you can solve this (probably very simple) problem:
My goal is to write this somewhere in the code:
1 2
Car *mycar = new GCar();
myCar->SetParam(new GParam());
To do this, I created the following classes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class Car
{
virtualvoid SetParam(Param *aa) = 0;
};
class GCar: public Car
{
virtualvoid SetParam(GParam *aa) {a = aa;} //Overrides the SetParam from Car, right?
GParam *a;
};
class Param
{
};
class GParam: public Param
{
};
However, I get a 'cannot instantiate abstract class' error on this line myCar->SetParam(new GParam());. I don't get it, can anybody help?
Your error is because Car contains a pure virtual. Any class containing a pure virtual is abstract and no objects of it (including pointers) may be declared.
class GCar: public Car
{
virtual SetParam(GParam *aa) {a = aa;} //Overrides the SetParam from Car, right?
GParam *a;
};
You are not overriding the virtual method because the method signature changed. The parameter is now GParam, but the virtual method was defined with Param.
As PanGalactic noted, functions are only virtual if they have the same name *and* argument list. So you'd need GCar::SetParam to take a Param, or Car::SetParam to take a GParam. Alternatively, you could create a wrapper that encapsulates this inheritance hierarchy, or you could set up a virtual in the Param hierarchy that handles how SetParam responds when it takes one.
Like I said, if you want to declare any object of Car you need to make Car::setparam a non-pure function. It's that simple.
Thanks for the hints! So Car should not contain any pure virtual methods? How should I design the classes in order to be able to write
So, if I understand correctly, you want to SetParam() behave differently if the object is a GCar and the paramter is GParam?
I believe, your class hierarchy is broken somewhere. Could you post more information about what is the purpose of Param and GParam?
tummychow wrote:
Any class containing a pure virtual is abstract and no objects of it (including pointers) may be declared.
You can declare pointers and references of classes which contain pure virtual methods.
1 2 3 4 5 6 7 8 9 10 11
struct Base {
virtualvoid f() = 0;
};
struct Derived : Base {
virtualvoid f() {}
};
int main() {
Base *b = new Derived;
}
Car *c;
if (blup)
c = new GCar();
c->SetParams(new GParams(1,2,3,4));
elseif (blap)
c = new FCar();
c->SetParams(new FParams(1,2,3,4,5,6));
[...]
doCrazyStuff(c);
And, just now, I found a solution and it's ridiculously simple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class Car
{
};
class GCar: public Car
{
void SetParam(GParam *aa) {a = aa;}
GParam *a;
};
class Param
{
};
class GParam: public Param
{
};
ect.
and then I use it as follows:
1 2 3 4 5 6 7 8 9 10 11 12
Car *c;
if (blup)
GCar *gc = new GCar();
gc->SetParams(new GParams(1,2,3,4));
c = gc;
elseif (blap)
FCar *fc = new FCar();
fc->SetParams(new FParams(1,2,3,4,5,6));
c = fc;
[...]
doCrazyStuff(c);