skydoor
skydoor

Reputation: 25878

redefine a non-virtual function in C++

When I read Effective C++, it says, never redefine a non-virtual function in C++.

However, when I tested it, the code below compiles correctly. So what's the point? It's a mistake or just a bad practice?

class A {

    public:
    void f() { cout<<"a.f()"<<endl;};   
};

class B: public A {
    public:
    void f() { cout<<"b.f()"<<endl;};   
};


int main(){

    B *b = new B();
    b->f(); 
    return 0;
}

Upvotes: 12

Views: 4914

Answers (3)

bmargulies
bmargulies

Reputation: 100051

Redefining a non-virtual function is fine so long as you aren't depending on virtual dispatch behavior.

The author of the book is afraid that you will pass your B* to a function that takes an A* and then be upset when the the result is a call to the base method, not the derived method.

Upvotes: 29

Kyle Lutz
Kyle Lutz

Reputation: 8036

The point is that if you, for instance, have a list of pointers to the base class (List<A *> list) and then call f(), the re-implemented method in B will not be called.

Upvotes: 2

Kornel Kisielewicz
Kornel Kisielewicz

Reputation: 57555

Try this:

int main(){
    A *b = new B();
    b->f(); 
    return 0;
}

I think the answer will be obvious once you see the result ;-).

Without being virtual, the late-binding mechanism will not be used, hence the function that is defined for that pointer type will be used, not late-binded function that you want to call. This leads to tons of badly trackable bugs.

Hence, what you are doing is creating a new function. It may be what you intended, but someone reading your code afterwards might expect the above code to work with late-binding. Very confusing.

One of the features I really wanted to see is a warning in such a case, with a "redefine" keyword to prevent it, but dreams are dreams, and reality is reality -_-

Upvotes: 9

Related Questions