Should I include member definitions in a class which delegates the implementation to a subclass?
Say I have an abstract class "Base", of which another abstract class "Subclass" extends. Base has a number of abstract member functions, and "Subclass" implements a number of them, but leaves it's own subclasses to provide the implementation of others. Should I include the signature of the member functions which I don't implement in the intermediate class or not?
In other words, assuming I have the following class structure:
Car.hpp:
class Car {
public:
virtual std::string getMake() = 0;
virtual std::string getType() = 0;
virtual ~Car { };
}
SportsCar.hpp:
class SportsCar : public Car {
public:
std::string getType开发者_如何学C();
// Do I need to specify virtual std::string getMake() = 0; here?
}
SportsCar.cpp:
std::string SportsCar::getType()
{
return "sports";
}
FerrariSportsCar.hpp:
class FerrariSportsCar : public SportsCar {
public:
std::string getMake();
}
FerrariSportsCar.cpp:
std::string FerrariSportsCar::getMake()
{
return "ferrari";
}
Should I still need include virtual std::string getMake() = 0;
in SportsCar.hpp?
The code compiles whether I include it or not, and the program seems to execute exactly the same.
You don't need to specify the abstract method again in the intermediate class. It will be inherited by the intermediate class as pure and still require it to be overridden in a further child.
Note that your intermediate class will still be abstract and you couldn't create instances of it.
Since it compiles both ways, this is somewhat a matter of style. I follow a general rule of "do as little work as possible". I think it applies here.
Omitting it will cause a compilation error for those who try to subclass SportsCar without implementing getMake(). Not repeating the definition in the intermediate class makes it easier to change the interface in the future.
There is one case where I would potentially put the intermediate pure virtual for readability purposes, which is when you have something like:
template<typename T>
class Foo : public T {...};
In this case, since it's difficult to find out the type of T, there's some value in putting the extra definition.
Not only you don't need to re-specify pure virtual member function declarations in intermediate classes of your hierarchy, but I would advise against doing so: when programming in C++ one has to get used to look for things in all the places they might legitimately be. By the way this is true also of many other programming languages.
精彩评论