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.

3
  • 2
    // virtual or not? - obviously not, as it is not declared as virtual. Commented Jan 13, 2018 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 . . . Commented Jan 13, 2018 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. Commented Jan 13, 2018 at 18:52

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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:
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();
}

2 Comments

Many thanks. Searching on "virtual without explicit pointers" led me here: stackoverflow.com/questions/25276635/…. That's what I was missing: the this pointer. (doh).
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.