虚拟功能签名不匹配及其行为

Virtual Function Signature Mismatch and its behavior

本文关键字:不匹配 功能 虚拟      更新时间:2023-10-16

我正在查看虚拟函数行为的示例案例。鉴于此测试代码,我对其行为有一些问题。

class A
{
public:
    A(int x)
    {
        cout << "In A Constructor" << endl;
        print();
    }
    ~A(){
        cout << "In A Destructor" << endl;
        delete _val;
    }
    virtual void print() { cout << "A." << endl; }
private:
    char* _val;
};
class B: public A
{
public:
    B(int x, int y) : A(x)
    {
        _dVal = new char[y];
        cout << "In B Constructor 1" << endl;
        print();
    }
    B() : A(0)
    {
        _dVal = new char[1];
        cout << "In B Constructor 2" << endl;
        print();
    }
    ~B(){
        cout << "In B Destructor" << endl;
        delete _dVal;
    }
    void print() { cout << "B" << endl; }
private:
    char* _dVal;
};
int main(int argc, char** argv) {
    A* p1 = new B();
    p1->print();
    delete p1;
    return 0;
}

输出为:

In A Constructor
A.
In B Constructor 2
B
B
In A Destructor

1)如果A类是唯一将其称为虚拟函数的级别,为什么打印为B类,并且通过删除( ->)调用它?2)为什么如果构造函数被称为构造函数,则为什么永远不会被调用?

1)如果A类是唯一将其称为虚拟函数的级别,为什么打印为B类,并且通过删除( ->)调用它?

这就是虚拟函数应该做的。指针p1是类型A*的,但实际上指向B类型的对象。只有在使用指针或对基类的引用来处理派生类时,这种动态绑定才会发生。

还请注意,派生类中的覆盖函数也是虚拟的(是否在声明中使用了关键字虚拟)。

2)为什么如果构造函数被称为构造函数,为什么永远不会被调用?

B的破坏者之所以被调用,是因为您没有声明基类的破坏者(即A::~A)为虚拟驱动器。对于这种情况,行为是不确定的。B的构造函数之所以称呼,是因为您通过new B()明确构建B