我有以下一段代碼(來自Koening & Moo Accelerated C++ 255頁),它定義了一個通用句柄類Handle
。 Handle
用於管理對象的內存:刪除句柄類中的對象可能導致未定義的行爲
#include <iostream>
#include <stdexcept>
///Handle
template <class T>
class Handle
{
public:
Handle() : p(0) {}
Handle &operator=(const Handle &);
T *operator->() const;
~Handle() { delete p; }
Handle(T *t) : p(t) {}
private:
T *p;
};
template <class T>
Handle<T> &Handle<T>::operator=(const Handle &rhs)
{
if (&rhs != this)
{
delete p;
p = rhs.p ? rhs.p->clone() : 0;
}
return *this;
};
template <class T>
T *Handle<T>::operator->() const
{
if (p)
return p;
throw std::runtime_error("error");
};
class test_classA
{
friend class Handle<test_classA>;
private:
virtual test_classA *clone() const { return new test_classA; }
public:
virtual void run() { std::cout << "HiA"; }
};
class test_classB : public test_classA
{
private:
virtual test_classB *clone() const { return new test_classB; }
public:
virtual void run() { std::cout << "HiB"; }
};
int main()
{
Handle<test_classA> h;
h = new test_classA;
h->run();
return 0;
}
當我編譯這個使用g++ -o main main.cpp -Wall
我得到警告:
warning: deleting object of polymorphic class type ‘test_classA’ which has non-virtual destructor might cause undefined behaviour [-Wdelete-non-virtual-dtor]
~Handle() { delete p; }
我不太明白的警告。句柄類自動刪除析構函數中的指針*p
,無論它的類型如何,那麼潛在的陷阱在哪裏?
偏題:留意[三規則](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-ree)。 'Handle'缺少一個拷貝構造函數。 – user4581301
@ user4581301不是'處理(T * t):p(t){}'拷貝構造函數嗎? – BillyJean
'句柄(T * t):p(t){}'是一個將'p'初始化爲給定值的構造函數。一個拷貝構造函數根據現有的實例創建一個新的實例,看起來像這樣:'Handle(const Handle&source)'。在這種情況下,你可能不想複製,也可能通過刪除拷貝構造函數'Handle(const Handle&source)= delete;'來替代它,否則會爲'p'創建一個新的'T' at:'Handle(const Handle&source):p(new T(source.p){}'但是你這樣做,你不需要兩個'Handles'具有相同的'p'。 – user4581301