我在阅读More Effective C++中的 item28 时遇到了一个问题。在这个项目中,作者向我们展示了我们可以使用成员模板,SmartPtr
以便SmartPtr<Cassette>
可以将其转换为SmartPtr<MusicProduct>
.
下面的代码和书中的代码不一样,但是效果是一样的。
#include <iostream>
class Base {};
class Derived : public Base {};
template<typename T>
class smart {
public:
smart(T* ptr)
: ptr(ptr)
{}
template<typename U>
operator smart<U>()
{
return smart<U>(ptr);
}
~smart()
{
delete ptr;
}
private:
T* ptr;
};
void test(const smart<Base>& ) {}
int main()
{
smart<Derived> sd(new Derived);
test(sd);
return 0;
}
它确实可以编译而没有编译错误。但是当我运行可执行文件时,我得到了一个核心转储。我认为这是因为转换运算符的成员函数做了一个临时智能,它有一个指向相同 ptr 的指针sd
(它的类型是smart<Derived>
)。所以 delete 指令运行了两次。更重要的是,在调用 test 之后,我们再也不能使用sd
了,因为ptr
insd
已经被删除了。
现在我的问题是:
- 我的想法对吗?还是我的代码和书中的原代码不一样?
- 如果我的想法是正确的,有什么方法可以做到这一点吗?
非常感谢您的帮助。