如何在构造函数中正确初始化wchar_t指针,并在析构函数中删除它

How to initialize wchar_t pointer correctly in constructor and delete it in destructor

本文关键字:指针 析构函数 删除 wchar 构造函数 初始化      更新时间:2023-10-16

我想在我的类中初始化一个wchar_t*

这是我的构造函数:
Book::Book()
{
    book = 0;
    auth = 0;
    setBook(TEXT(""));
    setAuth(TEXT(""));
}

这是析构函数:

Book::~Book()
{
    if (book)
        delete book;
    if (auth)
        delete auth;
}

这里是setBook():

void Book::setBook(TCHAR *a) {
    if (book)
        delete book;
    book = new TCHAR[lstrlen(a) + 1];
    lstrcpy(book, a);
}

问题是,当我试图创建新对象并将其推到vector时,当在析构函数中删除book时,我得到一个运行时错误"程序已触发断点"。

这是我的向量:

for (int i = 0; !feof(f); i++) {
        reqBook.push_back(Book());
        reqBook[i].read(f);
    }

如果管理资源,必须具有复制构造函数和复制赋值操作符(或删除它们)。这就是"三法则"。在c++ 11中,有一个move构造函数和一个move赋值操作符(规则5)是个好主意。

如果您尝试使Book成为管理资源的类,您将发现在复制或构造bookauth的过程中涉及到异常安全的一些复杂性。

解决方案是写一个RAII类封装处理wchar_t的数组,并使bookauth都是该类的对象。当你这样做的时候,你会发现你已经做了一个穷人的std::wstring副本。

唯一的不使用std::wstring的原因是,如果它是一个类分配,你已经被明确禁止使用它。

崩溃的具体原因是std::vector复制了原来的Book对象。当它这样做时,它使用编译器生成的复制构造函数(因为您没有提供一个)。这只是复制指针。原始对象的析构函数删除了这些指针指向的内存,现在你就陷入了被称为"未定义行为"的痛苦世界。当vector中的对象被删除时,它也会尝试删除相同的内存,任何事情都可能发生——遇到断点是一个特别无痛的结果。