我有以下问题。我创建一个类,并将指向该类的指针存储在另一个类中。创建后,一切都很好。然而,一步之后似乎该课程已经消失。
我在这里写了一个非常简单的测试场景:
#include <iostream>
using namespace std;
class test
{
public:
test();
bool ok;
};
test::test()
{
ok = false;
}
class func
{
public:
func();
void check();
test *pTest;
};
func::func()
{
test temptest = test();
cout << temptest.ok << endl;
pTest = &temptest;
cout << pTest->ok << endl;
}
void func::check()
{
cout << pTest->ok << endl;
};
int main( int argc, char *argv[] )
{
func mFunc = func();
// what happens here
mFunc.check();
}
以上程序输出以下内容:
0
0
204
从204开始,我猜想我之前创造的课程已经消失了。
你能告诉我发生了什么事吗?为什么?
答案 0 :(得分:1)
以上都是正确的。我期待你寻求的简单解决方案是
pTest = new test();
而不是分配给局部变量,然后指向该变量。
答案 1 :(得分:1)
问题是您正在创建一个具有“有限”范围的对象。
func::func()
{
test temptest = test(); // temptest construction
cout << temptest.ok << endl;
pTest = &temptest;
cout << pTest->ok << endl;
} // temptest descrution
构造func之后,pTest现在引用一个无效的对象。
您必须使用动态内存或共享指针来管理指针。
#include <iostream>
using namespace std;
class test
{
public:
test();
bool ok;
};
test::test()
{
ok = false;
}
class func
{
public:
func();
~func();
void check();
test *pTest;
};
func::func()
{
pTest = new Test();
cout << pTest->ok << endl;
cout << pTest->ok << endl;
}
func::~func() { delete pTest; }
void func::check()
{
cout << pTest->ok << endl;
};
int main( int argc, char *argv[] )
{
func mFunc = func();
// what happens here
mFunc.check();
}
现在test的构造函数分配一个新对象并存储该对象的地址,析构函数可以释放内存。以这种方式管理内存不是一个好的prectice。
使用共享指针,如shared_ptr或unique_ptr,但这需要一些其他知识,如移动语义。
答案 2 :(得分:0)
func对象的生命周期超出了所包含的pTest对象实例的生命周期。
一旦构造函数func返回,其成员pTest指向的对象现在不再有效(temptest,当func :: func时,func :: func()范围内的auto / stack测试实例已被销毁返回)。
答案 3 :(得分:0)
当调用func类函数func()时,对象temptest
被分配在堆栈上。然后将该存储器的地址存储在指针pTest
中。当函数func()超出范围时,堆栈展开并且对象temptest
被破坏。指针pTest
现在指向未分配的数据,这会产生未定义的结果。
像这样创建的对象:
test t;
称为自动对象,当它们超出范围时会自动解除分配。
您应该了解动态分配数据和使用自动对象的不同之处。您还可以阅读有关堆栈和堆内存的内容,我认为这可以为此事提供一些启示。