11 ms·
I agree with "composition over inheritance", but I disagree with "inheritance is evil". Composition over inheritance means you divide you classes into parts tha
by ajuc 12y ago
I agree with "composition over inheritance", but I disagree with "inheritance is evil". Composition over inheritance means you divide you classes into parts that ALSO use inheritance and virtual methods, you just don't make the hierarchy deep and don't mix many different subdivisions into one hierarchy. The problem isn't virtual methods, it's too many divisions and responsibilities in one class hierarchy.
And you do want to refactor your virtual methods and then extracted methods do usually need to be virtual, even if at first they don't they may need to become virtual in future, and IMHO it's better to just make them virtual from the start, if you don't REALLY need the performance.
You can mess up because of nonvirtual-by-default too, especially in C++ because of the difference between stack and heap objects.
struct A {
virtual int f(int x, int y) { return g(x,y); }
int g(int x, int y) { return x+y; }
};
struct B : public A {
int f(int x, int y) { return g(x,y)+1; }
int g(int x, int y) { return x+y-1; }
};
B* b1 = new B();
A* b2 = b;
B b3;
b1->f(2,2); // 4
b2->f(2,2); // 5
b3.f(2,2); // 4
This bite me a few times in C++.
- slavik81 12y agoThose actually all return 4. Since f is virtual in the base class, it remains virtual in all derived classes, regardless of whether they say so explicitly. The override keyword was added in C++11 to help prevent the sort of mistake you were trying to show. Any methods you mark with it will result in a compile error if they are not actually overriding anything. For example, if B::g were marked as override, it would fail to compile because A::g is not virtual.