C ++继承和虚函数

时间:2018-01-13 18:29:16

标签: c++ inheritance virtual

通过阅读教科书,我得到的印象是,当使用指针或对象的引用时,覆盖虚函数才有效。本书演示了如何创建指向派生类类型的对象的基类类型的指针,并使用它来演示虚函数覆盖。

但是,我现在遇到以下问题。看起来不是一个指针,我期待将function1虚拟化不会有所作为,但确实如此。我在这里明显遗漏了一些东西,并希望得到一个关于它是什么的解释。对不起,如果我的解释不清楚;我也希望之前有过这样的问题,但无法提出要搜索的内容。

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"; }

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

它不是虚拟功能,因为它没有标记为一个。它只是来自派生类/对象的公共函数可访问。您的代码也没有表现出多态行为。话虽如此,您的所有功能都不是virtual也不是overriding。多态安装的简单示例是:

#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
}

或通过参考:

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

如果您不使用多态行为,将函数标记为virtualoverride几乎没有什么好处。

答案 1 :(得分:0)

function1不是虚拟的,obj2调用classB function1,因为它是一个clasB对象,编译器首先查看函数的派生类型最多,然后是最左边的基类(并通过该库的基础),以及然后是多重继承情况下的下一个基础。如果你把classA *带到obj2并调用了function1,它将调用classA function1。

答案 2 :(得分:0)

没有显式指针的虚拟示例:

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