初始化派生类时使用虚函数

Usage of virtual functions when initializing a derived class

本文关键字:函数 派生 初始化      更新时间:2023-10-16

下面是我将基于我的问题的代码示例:

using namespace std;
class A {
    public:
        A(char *t) {
            cout << "A: " << t << endl;
        }
        virtual void printInfo() {}
};
class B : public A {
    public:
        B(char *t, char *tt) : A(t) {
            cout << "B: " << tt << endl;
        }
        virtual void printInfo() {
            cout << "B class";
        }
};
class C : public B {
    public:
        C(char *t, char *tt, char *ttt) : B(t, tt) {
            cout << "C: " << ttt << endl;
        }
        virtual void printInfo() {
            cout << "C class";
        }
};
int main(int argc, char *argv[]) {
    C c("Hello", "to", "you");
    A *a = &c;
    a->printInfo();
    //This program prints:
    //A: Hello
    //B: to
    //C: you
    //C class
    return 0;
}

考虑到我的C类构造函数初始化B,而B执行A,我将如何在B类中调用虚函数?或者这是一种完全错误的方法?

int main()
{
    C c("Hello", "to", "you");
    A* a = &c;
    a->printInfo();  // "C class"
}

由于关键字virtual,执行虚拟调度,调用最派生的printInfo

您可以禁用虚拟调度并调用特定的函数:

a->A::printInfo();   // "A class"

因为aA*,所以通常的函数调用规则适用。

这里遗漏的羊是B::printInfo():

a->B::printInfo();  // error: 'B' is not a base of 'A'

B::printInfo既不是最派生的重写,也不是A的成员。因此,为此,您必须向编译器保证a确实指向C(或者至少指向B):

static_cast<B*>(a)->B::printInfo();
                    // "B class"

恶心。

一般来说,当这种"需求"出现时,你应该质疑你的方法,因为它散发出糟糕的设计味道。