gpt4 book ai didi

c++ - 虚拟析构函数和未定义的行为

转载 作者:IT老高 更新时间:2023-10-28 22:25:19 26 4
gpt4 key购买 nike

这个问题不同于“我何时/为什么应该使用 virtual 析构函数?”。

struct B {
virtual void foo ();
~B() {} // <--- not virtual
};
struct D : B {
virtual void foo ();
~D() {}
};
B *p = new D;
delete p; // D::~D() is not called

问题:

  1. 这是否可以归类为未定义的行为(我们知道 ~D() 不会被称为肯定)?
  2. 如果 ~D() 为空怎么办。它会以任何方式影响代码吗?
  3. 在将 new[]/delete[]B* p; 一起使用时,~D() 肯定不会被调用,不管析构函数的 virtualness。是吗未定义的行为或明确定义的行为?

最佳答案

何时/为什么应该使用虚拟析构函数?
关注 Herb Sutters guideline :

A base class destructor should be either public and virtual, or protected and nonvirtual

这是否可以归类为未定义的行为(我们知道 ~D() 肯定不会被调用)?

根据标准,它是未定义的行为,这通常会导致未调用派生类析构函数并导致内存泄漏,但推测未定义行为的后效应是无关紧要的,因为标准不保证任何东西在这方面。

C++03 标准:5.3.5 删除

5.3.5/1:

The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression.
delete-expression:
::opt delete cast-expression
::opt delete [ ] cast-expression

5.3.5/3:

In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.73)

如果 ~D() 为空怎么办。它会以任何方式影响代码吗?
根据标准,它仍然是未定义的行为,派生类析构函数为空可能只会使您的程序正常工作,但这又是特定实现的实现定义方面,从技术上讲,它仍然是未定义的行为。

请注意,这里没有保证不将派生类析构函数设为虚拟就不会导致对派生类析构函数的调用,这个假设是不正确的。根据标准,一旦您在未定义行为领域越界,所有赌注都将取消。

注意他的标准对未定义行为的规定。

C++03 标准:1.3.12 未定义行为 [defns.undefined]

behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this International Standard imposes no requirements. Undefined behavior may also be expected when this International Standard omits the description of any explicit definition of behavior. [Note: permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed. ]

如果只有派生的析构函数不会被调用,则由上面引用中的粗体文本控制,这显然对每个实现都是开放的。

关于c++ - 虚拟析构函数和未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8599225/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com