提问人:username 提问时间:9/10/2023 最后编辑:Some programmer dudeusername 更新时间:9/10/2023 访问量:55
对象实例在销毁后仍可访问
Object instance still accessible after destruction
问:
我有一个将 struct 作为数据成员的结构,我的问题是为什么即使在销毁后(如输出中所示)仍然可以通过分配的实例(在 ) 中创建的实例访问Animal
Dog
Dog
Animal
Animal
Dog
struct Dog {
Dog() {}
Dog(std::string n) : name(n) {std::cout << "dog constructed\n";}
~Dog() {std::cout << "dog destructed\n";}
std::string name;
};
struct Animals {
Animals() {std::cout << "animal constructed\n";}
~Animals() {std::cout << "animal destructed\n";}
Dog dog;
};
Animals* foo() {
Animals* animals = new Animals;
animals->dog = Dog("layka");
return animals;
}
int main() {
Animals* animals = foo();
std::cout << animals->dog.name << std::endl;
delete animals;
}
输出:
animal constructed
dog constructed
dog destructed
layka
animal destructed
dog destructed
还有人可以解释为什么动物在狗之前被摧毁吗?为什么它被摧毁了两次,而只建造了一次?
我没想到它被摧毁后会有同样的价值dog.name
答:
0赞
user10
9/10/2023
#1
动物构造
狗构造:一些临时开始的构造及其副本 存储在
Dog("layka")
animals->dog
狗被毁:一些被建造的狗开始被破坏 但和它的名字一起活着。
Dog("layka")
animals->dog
莱卡
animal destructed:Animal destructor 的开始,但不是它的结束
狗被毁:析构函数的开始
animals->dog
动物在它只是先开始破坏器之前没有被破坏。下面的示例显示了 Animal 的析构函数中发生的情况:animals->dog
~Animals() {
std::cout << "animal destructed\n"; //animal still exist
std::cout << "dog destructed\n";// animals.dog still exist
//destroys animals.dog.name
//destroys whole animals.dog
//animal exist but animals->dog no more
//destroys whole animal
}
评论
0赞
Ted Lyngmo
9/10/2023
你能澄清一下“输出顺序不是破坏顺序”是什么意思吗?
0赞
username
9/10/2023
好吧,但是为什么副本连同它的名字一起还活着,它不是在堆栈上创建的吗?我知道它是分配的动物对象的一部分,但(我认为)这还不足以延长狗对象的生命周期。
0赞
user10
9/10/2023
在animals->dog中复制狗不是对狗(“layka”)中创建的狗的引用,它是全新的狗,有自己的寿命。
评论
animals->dog = Dog("layka")
Dog
animals->dog
animal
dog
animals
Dog
Animals
Dog
Dog
animals->dog
Animals
Animals
struct A { int d; };
A* a = new A; a->d = 5;
5
A
a