相关疑难解决方法(0)

为什么通过基指针删除[]一组派生对象是未定义的行为?

我在C++ 03标准中找到了以下片段5.3.5 [expr.delete] p3:

在第一个备选(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或者行为未定义.在第二个备选(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义.


快速回顾静态和动态类型:

struct B{ virtual ~B(){} };
struct D : B{};

B* p = new D();
Run Code Online (Sandbox Code Playgroud)

静态类型pB*,而动态类型*pD,1.3.7 [defns.dynamic.type]:

[ 例如:如果一个p静态类型为"指向"的指针class B指向一个对象class D,B该表达式的动态类型*p是" D."]


现在,再次查看顶部的引用,这意味着如果我正确的话,下面的代码会调用未定义的行为,无论是否存在virtual析构函数:

struct B{ virtual ~B(){} };
struct D : B{};

B* p = new D[20];
delete [] p; // undefined behaviour here …
Run Code Online (Sandbox Code Playgroud)

c++ undefined-behavior dynamic-arrays delete-operator

36
推荐指数
2
解决办法
6448
查看次数

虚析构函数:不动态分配内存时是否需要?

如果我的类没有动态分配任何内存,我们是否需要虚拟析构函数?

例如

class A
{
      private: 
      int a;
      int b;

      public:
      A();
      ~A();
};

class B: public A
{     
      private:
      int c;
      int d;

      public:
      B();
      ~B();
};
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们需要将A的析构函数标记为虚拟吗?

c++ virtual-destructor

20
推荐指数
2
解决办法
4820
查看次数

添加从unique_ptr <T>到T*的隐式转换

一般问题:如果不考虑它是否是一个好主意,我如何将一个隐式转换运算符添加到已经定义的类中?例如,假设我想要unique_ptr <T>隐式转换为T*,但我不能只添加成员转换运算符,因为我无法更改unique_ptr类的定义.

选项:

  1. 是否有一些c ++巫毒可以用来实现这一点而无需创建成员函数?
    答案 - 远:没有.
    无法从无法在代码中修改的类型添加隐式转换.
    只是......悲伤.

  2. 我可以从std :: unique_ptr派生并添加我自己的成员转换函数吗?这有什么严重的缺点吗?
    Answer-So-Far:是的(来自vsoftco)
    下行尚未确定.到目前为止继承自std :: unique_ptr,继承其构造函数,并声明一个隐式转换运算符,几乎没有任何需要编写的代码.

  3. 我将不得不在余生中生活吗?
    答案 - 迄今为止:我们会看到......
    如果我可以选择2运行而没有任何严重的副作用或负担,我会测试一段时间并报告我是否认为值得.走着瞧!

示例代码:

#include <algorithm>
#include <memory>
#include <vector>

struct MyClass
{
    MyClass(int v) : value(v) {}

    int value;
};

int main()
{
    auto vec = std::vector<std::unique_ptr<MyClass>>();

    vec.push_back(std::make_unique<MyClass>(1));
    vec.push_back(std::make_unique<MyClass>(2));

    // error C2664: 'void (__vectorcall *)(MyClass *)' : cannot convert argument 1 from 'std::unique_ptr<MyClass,std::default_delete<_Ty>>' to 'MyClass *'
    std::for_each(std::begin(vec), std::end(vec), [](MyClass* myClass)
    {
        myClass->value += 3;
    });
}
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr implicit-conversion

7
推荐指数
1
解决办法
1064
查看次数

为什么析构函数总是声明为虚拟

可能重复:
何时使用虚拟析构函数?
虚析构函数和未定义的行为

我是c ++和编程的新手,我观察到析构函数总是被声明为虚拟的.我可以知道为什么会这样吗?

提前致谢

c++ destructor

3
推荐指数
1
解决办法
6613
查看次数

"删除"是否与多态性一起正常工作?

BaseClass * p = new DerivedClass();
delete p;
Run Code Online (Sandbox Code Playgroud)

我知道第二行将调用基类的析构函数,如果它没有虚拟析构函数和派生类的析构函数,如果它有,但会delete正确释放内存(让我们说BaseClass's对象占用8个字节的空间,DerivedClass一个12 - 它会释放8或12个字节)并在任何一种情况下摆脱对象?

c++ virtual-destructor

3
推荐指数
1
解决办法
2751
查看次数