gpt4 book ai didi

c++ - 在分配新对象之前未删除对象

转载 作者:行者123 更新时间:2023-11-30 01:10:01 25 4
gpt4 key购买 nike

我有点困惑,因为我确信这应该会有所不同。看看这个代码示例:

#include <iostream>
#include <string>

using namespace std;

class base
{
public:
virtual ~base() = default;
};

class derived : public base
{
private:
int a = 0;
int *b = nullptr;
std::string lol;

public:
derived(std::string s) : b(new int(6)), lol{s} { cout << "ctor " << lol << endl; }
derived(derived const& d) : lol{d.lol + " copy"} {cout << "copy " << lol << endl; }

virtual ~derived() { cout << "dtor " << lol << endl; delete b; }

virtual void superFunction() { cout << "OMG " << lol << endl; }
};

int main()
{
derived a("a");
derived b("b");
a = b;
}

关闭所有优化后的程序输出是:

ctor a
ctor b
dtor b
dtor b

我确信在这种情况下,编译器应该生成删除对象 a 并使用复制构造函数创建新对象的代码。相反,它使用隐式声明的 operator=

谁能解释一下为什么?或者指出 C++ 标准。

谢谢。

最佳答案

当你写a = b;时,编译器会调用赋值运算符,如果代码中没有赋值运算符并且没有被标记为已删除,它会自动生成。仅当您尝试从另一个对象初始化一个新对象时才使用复制构造函数,如下所示:

derived a("a");
derived b = a;

此外,您的代码在 main 返回之前崩溃,因为它试图删除 b,它指向 ab 中的同一内存在 a = b; 默认赋值之后。

如果你想在 a = b; 执行后用 derived 析构函数删除 a,你只需要 copy-and-swap 惯用语. What is the copy and swap idiom?关于如何在遗留和现代 C++ 中做到这一点有很好的答案。从该答案中正确实现四法则将完全符合 DRY 原则并帮助您避免内存问题。请注意将参数传递给 operator= 按值 的绝妙技巧,它使编译器选择适当的构造函数(复制或移动)并允许您只编写四个方法而不是所有方法five

关于c++ - 在分配新对象之前未删除对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39015510/

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