gpt4 book ai didi

不调用 C++ 析构函数

转载 作者:太空宇宙 更新时间:2023-11-04 16:02:28 26 4
gpt4 key购买 nike

我有三个类:房间、门和世界

#include <set>;

using namespace std;

class Door; // Forward declaration

class Room {
public:
Door* door1;
Door* door2;

Room(){}

~Room() {
delete door1;
door1 = 0;
delete door2;
door2 = 0;
}
};

class Door {
public:
Room* roomA;
Room* roomB;

Door(Room* roomA, Room* roomB) {
this->roomA = roomA;
this->roomB = roomB;
linkRooms(); // This sets up the Door-Pointers in the Rooms
// so they know about the new door.
}

~Door() {
// Returns the room-owned pointer pointing at this door
getMyRoomPointer(roomA) = 0;
getMyRoomPointer(roomB) = 0;
}

Door * & getMyRoomPointer(Room * const & room) {
if (room->door1 == this) return room->door1;
else return room->door2;
}

void linkRooms() {
roomA->door1 = this;
roomB->door2 = this;
}

};

class World {
public:
std::set<Room*> rooms;

World() {
// Set up two rooms and link them using a door
Room* newRoom = new Room();
rooms.insert(newRoom);
Room* anotherNewRoom = new Room();
rooms.insert(anotherNewRoom);

new Door(newRoom, anotherNewRoom);
}
~World() {
// Iterate over the rooms and call delete on all of them
for (std::set<Room*>::iterator it = rooms.begin(); it != rooms.end(); ++it) {
delete *it;
}
}
};

int main() {

World world;

return 0;
}

当运行 main 时,构造函数只用两个房间和一扇门填充世界,作为它们之间的链接。主要回归后,世界应该被删除,所有的房间和门也应该被照顾。

问题是,我的 Door 析构函数从未被调用过。因此,房间内的门指针未设置为空,当“另一边”的房间试图删除同一扇门时,我收到错误消息。

当我只是创建一个 Door 的实例,然后立即删除它时,我没有遇到任何问题:

int main(){

Room oneRoom;
Room anotherRoom;

Door* door = new Door(&oneRoom, &anotherRoom);
delete door; // works just fine

return 0;
}

问题:为什么不调用 Door 构造函数?是否允许像第一个示例中那样设置门?

我知道,我正在双重删除我房间的门指针,并且我可以(并且应该)使用 SmartPointers。现在我只是想知道为什么我要面对这种行为。毕竟,我对 C++ 还是个新手。

我现在确实设置了一个可运行的示例,它重现了错误。

最佳答案

您在定义Door 之前调用delete。因此程序的行为是未定义的,不能保证调用析构函数。

引自标准(草案)[expr.delete] :

  1. If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.

解决方案:如果类型的析构函数是非平凡的(即用户定义的,例如 ~Door,则在类型完成之前永远不要删除此类对象)。在这种情况下,在调用 delete 的函数之前定义 Door

作为一般规则,除非类类型完整,否则永远不能调用成员函数。不幸的是,对于析构函数,编译器可能并不总是能够捕获错误。附言。 g++ 会警告您的程序:warning: possible problem detected in invocation of delete operator: [-Wdelete-incomplete]

关于不调用 C++ 析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41120443/

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