tags:

views:

88

answers:

5
class Class1
{
public:
    void print()
    {
        cout << "test" << endl;
    }

    void printl()
    {
        print();
    }
};

class Class2 : public Class1
{
public:
    void print()
    {
        cout << "test2" << endl;
    }
};

Why does print() not get overridden in Class2, is there any way a function can be overridden like this? (Without virtual functions). Thanks

    Class2 t;
    t.printl();
+9  A: 

No. This is the entire reason for virtual functions.

Without a virtual method here, when printl() calls print(), it's calling Class1.print(), which prints "test". If you flag the method as virtual, then it will handle it as you were expecting.

Reed Copsey
Thanks, I was expecting that to be the case. Just it seems like this could be resolved at compile time.
Ben Reeves
You wouldn't want it to be resolved. The main reason to NOT mark the method as virtual is so that you can guarantee, when you call print(), YOUR print() gets called. If you want this behavior, as a class author, you should make the method virtual.
Reed Copsey
As far as it being reolved at compile time, that is something a compiler could do for your example (for a method marked `virtual` - without a virtual function you're describing different semantics to the compiler). Since the compiler can determine at compile time that the object is a `Class2` it would be possble for the compiler to call `Class2::print()` directly. I'm not sure how often this kind of optimization is done yet in the real world (or by which compilers).
Michael Burr
So in this case using virtual would incur no performance overhead? i.e. doesn't need to be resolved at run time?
Ben Reeves
@Ben Reeves: Virtual methods do incur some overhead, but it's very, very minor. C++ was designed with virtual method calls in mind. I, personally, would not worry about optimization at that level, but rather focus on getting your algorithm to perform correctly.
Reed Copsey
@Ben: in this case a compiler *might* be able to elide the virtual 'overhead' (which is really probably nothing to worry much about anyway). I suspect that most compilers don't normally perform this optimization, but I don't really know. Before worrying about optimization or what the compiler might do under the hood, programmers should worry first about describing the correct behavior they want from the compiler.
Michael Burr
+2  A: 

What you want is called a virtual method. Simply write virtual void print() where you currently have void print(), and it will work as you expect. Be aware that this will not work in constructors or destructors.

Tyler McHenry
+3  A: 

No, there is no way to override non-virtual functions. That's what virtual functions are for.

sepp2k
A: 

The call to print inside of printl is not overriden because it's not a virtual method. It`s a non-virtual method and hence is being invoked non-virtually. If you want to be overridable by a child class then make it virtual.

JaredPar
A: 

Imagine you had Class2, Class3 and Class3, all "overriding" Class1's "print" method.

When Class1::printl is called - how is it meant to know which of the 3 overrides to call? Without virtual methods the printl implementation has no way of knowing which overriding method to choose.

Chris Becke