Polymorphism and virtual setters

Hi,

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
{
   virtual void SetParam(Param *aa) = 0;   
};

class GCar: public Car
{
	virtual void  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?

Thanks!

Fabio
Last edited on
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.
1
2
3
4
5
6
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.
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
1
2
Car *mycar = new GCar();
myCar->SetParam(new GParam());
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.
fzuend wrote:
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 {
    virtual void f() = 0;
};

struct Derived : Base {
    virtual void f() {}
};

int main() {
    Base *b = new Derived;
}
Eventually I'd like to write something like:
1
2
3
4
5
6
7
8
9
10
Car *c;
if (blup)
  c = new GCar();
  c->SetParams(new GParams(1,2,3,4));
else if (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;
else if (blap)
  FCar *fc = new FCar();
  fc->SetParams(new FParams(1,2,3,4,5,6));
  c = fc;
[...]

doCrazyStuff(c);
The solution I was initially looking for was generics!

Something like

class Car <T: Param>{...};

class GCar: Car <GParam>{...};




Topic archived. No new replies allowed.