I've encountered the following situation in my C++ code (this is an example to illustrate the problem, and has not much to do with the actual code). I have a virtual class Family
and two classes that I derive from it:
class Family {
public:
virtual double operator()(double const & x) const = 0;
virtual ~Family();
};
class Mother : public Family {
public:
double operator()(double const & x) const override { return x*x; }
};
class Father : public Family {
public:
double operator()(double const & x) const override { return x-2; }
};
Then I have another class Car
. This class should have a private member that can be either an object from the Mother
or Father
class. I tried to implement this as
class Car {
public:
Car(Family member) : right_seat_(member) {}
private:
Family right_seat_;
};
If one tries to run the above via the main function
int main(){
Mother lucy = Mother();
Car Van = Car(lucy);
}
I get the error that member
in the constructor of Car
cannot be declared since Family
is abstract. I understand the problem and why this happens, but I don't know what the right tool in C++ is to solve the problem. Unfortunately I also don't know how to google this properly (I didn't really find any suitable suggestions).
The only idea that I had was to remove the abstract class altogether and template the Car
class. I'd like to avoid this, since in the original problem the two derived classes logically belong to a "superclass", so I don't want to introduce this split if it is not absolutely necessary.
You need to use references or pointers for polymorphism. One possible solution would be:
class Car {
public:
Car(Family* member) : right_seat_(member) {}
private:
Family* right_seat_;
};
int main(){
Mother* lucy = new Mother();
Car Van = Car(lucy);
...//do stuff with car
}
Don't forget to delete
the pointers once you are done with them.
If you can use c++11 (c++14 for std::make_unique) or higher, using smart-pointers is even better:
class Car {
public:
Car(std::unique_ptr<Family>&& member) : right_seat_(std::move(member)) {}
private:
std::unique_ptr<Family> right_seat_;
};
int main(){
std::unique_ptr<Family> lucy = std::make_unique<Mother>();
Car Van = Car(std:move(lucy));
...//do stuff with car
}