【发布时间】:2017-11-07 18:28:05
【问题描述】:
我对对象分配有一个奇怪的行为。如果您能解释为什么这项作业会这样工作,我将不胜感激。它已经花费了我很多时间。 我正在使用 Visual Studio Enterprise 2017(所有默认设置)。
代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Test
{
public:
Test()
{
cout << "Constructor of " << this << endl;
}
~Test()
{
cout << "Destructor of " << this << endl;
}
};
int main()
{
cout << "Assignment 1" << endl;
auto t = Test();
cout << "Assignment 2" << endl;
t = Test();
int i = 0;
cin >> i;
return 0;
}
输出(最高为 cin):
Assignment 1
Constructor of 006FFC9F
Assignment 2
Constructor of 006FFBC7
Destructor of 006FFBC7
预期输出(最高为 cin):
Assignment 1
Constructor of 006FFC9F
Assignment 2
Destructor of 006FFC9F
Constructor of 006FFBC7
我想编写一个测试函数来创建我的(模板)类的对象,进行一些测试,然后创建一个新对象并进行更多测试。问题是 t 在第二次赋值后保存了已经破坏的对象。 我知道我可以只使用导致预期行为的动态分配,但是为什么这个程序的行为不同?
非常感谢。 问候。
PS:结果是一样的,与 Release/Debug 或 64/32 位编译无关
编辑:更详细的示例:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Test
{
private:
float* val;
public:
Test()
{
val = new float;
cout << "Constructor of " << this << ", addr. of val: " << val << endl;
}
~Test()
{
cout << "Destructor of " << this << ", addr. of val: " << val << " --> DELETING VAL!" << endl;
delete val;
}
float* getVal() { return this->val; }
};
int main()
{
cout << "Assignment 1" << endl;
auto t = Test();
cout << "Assignment 2" << endl;
t = Test();
cout << "Val Address: " << t.getVal() << endl;
int i = 0;
cin >> i;
return 0;
}
输出(它在末尾保存了一个已删除的指针!!!):
Assignment 1
Constructor of 004FFBDC, addr. of val: 0072AEB0
Assignment 2
Constructor of 004FFB04, addr. of val: 00723928
Destructor of 004FFB04, addr. of val: 00723928 --> DELETING VAL!
Val Address: 00723928
【问题讨论】:
-
看看复制省略,从 C++17 开始在某些情况下必须执行。
-
auto t = Test();不是赋值,而是初始化。 -
在
t = Test();中你构造了一个Test的临时对象,传递给t的operator=,然后,销毁这个临时对象。为什么你认为,这是一个问题?如果您将 print 语句放入operator=(为了完整起见,可能还有复制构造函数),您会清楚地看到这种行为。 -
"t 持有第二次赋值后已经销毁的对象" 不,它没有持有新构建的对象,该对象已经替换了不再需要的对象。您的代码在任何时候都不需要两个
Test对象同时存在。 -
局部变量的生命周期直到它们被声明的代码块的结尾。所以你不应该期望看到
t的析构函数被调用直到你到达}结尾main.
标签: c++ class constructor visual-studio-2017 destructor