C++如何为基类casted对象调用纯虚拟方法

C++ How are pure-virtual methods called for base-class-casted objects?

本文关键字:调用 虚拟 方法 对象 casted 基类 C++      更新时间:2023-10-16

可能重复:
为什么派生类中的重写函数隐藏基类的其他重载?

嗨,

让我用这个例子来解释我的问题:

class A
{
    virtual ~A() = 0 { }
    A(const A&);
    virtual void operator =(const A&) = 0;
}
class B : public A
{
    ~B();
    B(const B&);
    void operator =(const B&);
}
void main(void)
{
    A* a = new B();
    delete a; // Is ~A() called, ~B() or both ?
}

这让我提出了两个问题:

  1. 在对抽象基类指针使用delete时,调用哪个析构函数
  2. 有可能用上面的复制方法之一复制我的对象"a"吗
  1. 两者都被调用。

    delete a中,派生类析构函数~B::B被找到并使用虚拟调度机制调用。~B::B的实现又隐式地调用基类析构函数~A::A。然而,此调用被实现为非虚拟普通调用,这意味着它不受~A::A被声明为纯的事实的影响。

    这就是为什么仍然需要定义纯虚拟析构函数的原因。尽管语言规范不允许对纯虚拟函数进行类内定义。即使您希望它是内联的,您仍然必须在类外定义它。

  2. 复制A类型的独立对象是不可能的,因为不可能有任何抽象类型的独立的对象。请澄清你的问题。你想复制什么?复制到哪里?

    如果你想做这样的

    B b1, b2;
    A *a1 = &b1, *a2 = &b2;
    *a1 = *a2;
    

    并且期望最后的分配表现得好像执行了CCD_ 7。。。好吧,这是可以做到的,但这需要一些努力,并且可能/将导致非常丑陋的代码。我想说,用这种功能来加重重载的赋值运算符的负担不是一个好主意。

virtual ~A() = 0 { }

这不会编译。纯虚拟析构函数看起来像:

virtual ~A() = 0;

即便如此,也必须添加一个实现,因为所有类继承结构的析构函数在破坏对象时都会被调用。因此,如果你不实现主体,这将导致UB(或者它甚至不会编译,因为我在gcc 4.6.3中没有这样做)。

1:~B()通过虚拟~A() = 0调用;则CCD_ 11调用CCD_。

此外,virtual ~A() = 0 { }是不正确的语法;您必须编写virtual ~A() = 0;,然后在类定义之外提供inline A::~A() { }

2:您的代码不会编译,因为B::operator=(const B&)不是A::operator=(const A&) = 0的可接受覆盖;对于虚拟方法,只允许函数返回类型是协变的。

没有简单的方法可以通过复制构造函数或赋值运算符来复制多态对象,因为这样的成员必须使用双重调度(请参阅虚拟赋值运算符C++)。通常的方法是使用一个virtual A *clone() = 0函数,该函数将返回派生类的new实例。

1)首先调用析构函数~B(),在析构函数_A()之后,记住这是:

在构造函数已被调用的情况下,析构函数将在相反的顺序。

2) 是的,因为它是指针,所以heritage可以阻止复制(通过recopy构造)