0

我有一个 Base 类,它被认为是只读的,在它的虚拟析构函数中它什么也不做。现在我将该 Base 类派生为一个可写的 Derived 类,并且在它的析构函数中,它删除了 Base 成员:

class Base
{
    virtual ~Base() {}
    void* Data;
}
class Derive : public virtual Base
{
    virtual ~Derive() { delete Data; }
}

忽略上面语法不正确的代码,如果我要将 Derive 实例传递给以 Base 类作为引用的 Function :

void Function(const Base& base)
{
   ...
}

...
Derive der = Derive();
...
Function(der);

Derived 析构函数会在函数作用域的末尾被调用吗?我在寻找正确的关键字来找到答案时遇到了麻烦,所以如果之前有人问过,我很抱歉。我假设 C++ 处理引用的类型是它们的类型,而不是它们可能的类型,但我可能是错的。

4

2 回答 2

3

不,它不会,因为对象不会超出范围。它超出范围,并在调用后自动销毁Function

{
  Derive der = Derive();
  //...
  Function(der);
  //...
  //der still alive here
} //der is destroyed here, all destructors are called correctly

如果您要按值而不是按引用传递参数:

void Function(Base base)
{
   ...
}

该对象将被切片。在内部创建的副本Function是类型Base(不是Derive)的对象,因此Base当函数退出时只会调用析构函数。

于 2012-10-09T14:12:02.893 回答
0

Derived 析构函数会在函数作用域的末尾被调用吗?

不会。当对象本身而不是对它的引用超出范围时,将调用 Derived 析构函数。引用不是对象。这只是一个别名。或者,将引用视为不能为空、不能重新分配、.用于访问成员而不是->. 除此之外,它们只是指针。当您将指针传递给函数时,仅仅因为指针在函数结束时超出范围并不意味着指向的对象超出范围。这同样适用于引用。

你的设计有点时髦。一些问题:

  • 类中的那个void*数据成员是Base怎么回事?
  • 为什么是void*指针?这有点 C 而不是 C++ 的味道。
  • 类中是否有任何成员函数Base使用该数据成员?
    • 如果不是,为什么该数据成员是该类的一部分?
  • ~Derive()删除了这一点,而不是~Base()有点怀疑。这种设计背后的基本原理是什么?
于 2012-10-09T14:32:40.617 回答