类析构函数是在赋值中调用的吗? 当已经保存对象的变量在C++代码中接收到另一个对象时,调用类析构函数?< /P> Car car1; Car car2; car1 = car2;

类析构函数是在赋值中调用的吗? 当已经保存对象的变量在C++代码中接收到另一个对象时,调用类析构函数?< /P> Car car1; Car car2; car1 = car2;,c++,C++,在这种情况下,car1析构函数是否会被调用?执行时,car1的析构函数将不会被执行 car1 = car2; 只有(可能隐式生成的)Car::operator=(const Car&) 析构函数只有在car1超出范围时才会被调用(或者当您显式调用它时,但实际上很少需要它) 还要注意的是,car1并不“持有”一个Car实例,它是实例本身。这取决于它。如果在堆上分配内存并将一个变量分配给另一个变量,则不会调用析构函数: { Car* car1 = new Car(); Car* c

在这种情况下,
car1
析构函数是否会被调用?

执行时,
car1
的析构函数将不会被执行

car1 = car2;
只有(可能隐式生成的)
Car::operator=(const Car&)car1
上调用code>

析构函数只有在
car1
超出范围时才会被调用(或者当您显式调用它时,但实际上很少需要它)


还要注意的是,
car1
并不“持有”一个
Car
实例,它是实例本身。

这取决于它。如果在堆上分配内存并将一个变量分配给另一个变量,则不会调用析构函数:

{
    Car* car1 = new Car();
    Car* car2 = new Car();
    car1 = car2;
}
但这会发生,因为它超出了范围,而不是因为拷贝分配

{
    Car car1;
    Car car2;
    car1 = car2;
}

您可以在以下程序中看到,直到main()函数结束时,才会为t1或t2调用析构函数:

#include <iostream>
#include <string>

class Test
{
    std::string _name;
public:
    Test(std::string name) : _name(name) { }
    ~Test()
    {
        std::cout << "Destructor " << _name << std::endl;
    }
    Test& operator=(const Test& fellow)
    {
        // avoid changing the name of the object
        std::cout << "Assignment operator " 
            << _name << "=" << fellow._name << std::endl;
        return *this;
    }
};

int main()
{
    Test t1("t1"), t2("t2");
    t1 = t2;
    return 0;
}
#包括
#包括
课堂测试
{
std::string _name;
公众:
测试(std::string name):\u name(name){}
~Test()
{
标准::cout
这会导致不执行
car1
的析构函数。

如果您希望调用析构函数,
car1
需要显式调用,否则它应该超出范围(正如我们的朋友Baum mit Augen所说,显式调用
car1
很少需要).

为什么不在代码中尝试它?只需从析构函数打印一些东西到控制台,看看是否打印出来。不,析构函数不会被调用。car1和car2是Car实例。@RenanJosé然后删除括号(),您是在声明函数而不是创建对象。如果Car类有一些向量作为类成员,那么在属性之后释放Car 1内存的最佳方法是什么?有什么让人如此困惑。它几乎向您展示了运算符=()默认情况下不会释放内存,在示例2中调用析构函数的唯一原因是由于作用域而不是赋值本身。@BenjaminLindley,move assignment操作符将从t2窃取资源,因此t2的析构函数将不会释放任何内容。move assignment操作符用于返回te之类的情况函数的临时值:t1=f()。而复制赋值运算符适用于本线程中讨论的情况:t1=t2。在复制赋值运算符中释放t1的资源有什么问题?我的错误。我将其误读为释放右侧操作数的资源。如果对象是常量,如何在赋值运算符中释放t1的资源?@RenanJosé你不能赋值给
const
对象,所以这个问题毫无意义。毫无疑问,赋值运算符调用t1=t2;?t1还是t2?
Car car1();//error, Car car1; call default construct function
Car car2(); //error, Car car2;call default construct function

car1 = car2; //call operator=() 
car1 = car2;