0

Reading through a text book, I have come away with the impression that overriding virtual functions only works when using a pointer or reference to the object. The book demonstrates the creation of a pointer of the base class type pointed to an object the derived class type, and uses that to demonstrate a virtual function override.

However, I've now come across the following. Not a pointer in sight, and I was expecting that making function1 virtual would not make a difference, but it does. I'm clearly missing something here and would appreciate an explanation as to what it is. Sorry if my explanation isn't clear; also I expect this has been asked before, but was unable to come up with what to search on.

using namespace std;

class ClassA
{
public:
    void function1(); // virtual or not?
    void function2();
};

class ClassB : public ClassA
{
public:
    void function1();
};

int main()
{
    ClassA objA;
    ClassB objB;

    objA.function1();
    cout << "\n";
    objA.function2();
    cout << "\n";
    objB.function1();
    cout << "\n";
    objB.function2(); // Fourth call
    cout << "\n";
}

void ClassA::function1() { cout << "ClassA::function1\n"; }

void ClassA::function2()
{
    cout << "ClassA::function2\n";
    function1(); // For the fourth call ClassA::function1()
                    // is called if ClassA::function1() is not virtual
                    // but ClassB:function1() is called if it is.  Why? 
}

void ClassB::function1() { cout << "ClassB::function1\n"; }

Many thanks for any help.

Hippo
  • 15
  • 3
  • 2
    `// virtual or not?` - obviously not, as it is not declared as `virtual`. –  Jan 13 '18 at 18:33
  • Sorry. I haven't explained myself clearly. I was using the comments in the code to ask the question. If A:function1 is as above (i.e. not virtual), this is the result of running to code: ClassA::function1 ClassA::function2 ClassA::function1 ClassB::function1 ClassA::function2 ClassA::function1 Press any key to continue . . . – Hippo Jan 13 '18 at 18:51
  • If I change it to be virtual, I get this: ClassA::function1 ClassA::function2 ClassA::function1 ClassB::function1 ClassA::function2 ClassB::function1 Press any key to continue . . . So making the function virtual does make a difference, and implements polymorphism (I believe). My point is that I wasn't expecting it to, and I'd like to know why. – Hippo Jan 13 '18 at 18:52

3 Answers3

1

It's not a virtual function as it is not marked as one. It's simply a public function accessible from a derived class / object. Your code is not exhibiting polymorphic behavior either. That being said none of your functions are virtual nor overriding. Trivial example for polymorphic installation would be:

#include <iostream>
#include <memory>

class ClassA {
public:
    virtual void function1() { // now virtual
        std::cout << "ClassA::function1\n";
    }
};

class ClassB : public ClassA {
public:
    void function1() override {
        std::cout << "ClassB::function1\n";
    }
};

int main() {
    std::unique_ptr<ClassA> p = std::make_unique<ClassB>();
    p->function1(); // now calls class B function, overrides class A behavior
}

or through references:

int main() {
    ClassB objB;
    ClassA& ro = objB;
    ro.function1(); // now calls class B function, overrides class A behavior
}

There is little benefit in marking functions as virtual and override if you are not utilizing polymorphic behaviour.

Ron
  • 14,674
  • 4
  • 34
  • 47
  • Sorry. I haven't explained myself clearly. I was using the comments in the code to ask the question. If A:function1 is as above (i.e. not virtual), this is the result of running to code: – Hippo Jan 13 '18 at 18:47
0

function1 is not virtual, obj2 calls the classB function1 because it is a clasB object, the compiler first looks at the most-derived type for a function, then the leftmost base (and on through the bases of that base), and then the next base in multiple inheritance situations. If you took a classA * to obj2 and called function1 it would call the classA function1.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
0

Example of virtual without explicit pointers :

class A
{
    public:
        virtual void f1()
        {
            cout << "A::f1()" << endl;
        }

        void f2()
        {
            f1();
        }
};

class B : public A
{
    public:
        void f1() override
        {
            cout << "B::f1()" << endl;
        }
};

int main()
{
    A a;
    B b;
    a.f2();
    b.f2();
}
Sid S
  • 6,037
  • 2
  • 18
  • 24
  • Many thanks. Searching on "virtual without explicit pointers" led me here: https://stackoverflow.com/questions/25276635/c-virtual-function-call-without-pointer-or-reference. That's what I was missing: the this pointer. (doh). – Hippo Jan 13 '18 at 19:02
  • https://stackoverflow.com/questions/5903443/c-polymorphic-call-without-explicit-pointer – Hippo Jan 13 '18 at 19:49