我正在使用的代码有自己的智能指针实现,它可以进行简单的引用计数.是的,我们不应该有自己的实施.是的,我们应该使用boost或者其中之一.忍受我. 我发现我想编写这样的代码: ...Coun
我发现我想编写这样的代码:
... CountedPointer<Base> base; ... CountedPointer<Derived> derived; ... base = derived;
但是,CountedPointer的复制构造函数有一个这样的原型:
CountedPointer(const CountedPointer<T> &other);
所以上面的代码将无法编译,因为它无法找到合适的构造函数(或赋值运算符 – 它在那里是相同的故事).我尝试用这样的原型重写复制构造函数:
template<U> CountedPointer(const CountedPointer<U> &other);
但是,我遇到了这样的问题:复制构造函数必须访问它正在复制的对象的私有成员(即原始指针),如果它在CountedPointer的不同专用中,则它们不可见.
Alexandrescu通过为封装指针提供访问器函数来避免在他的库Loki中出现这个问题,但是如果可能的话,我宁愿不直接访问原始指针.
有什么方法可以写这个来允许派生到基本副本,但不允许一般访问原始指针?
更新:
我已经实现了下面接受的答案,并且效果很好.当我只提供复制构造函数的模板化版本时,我花了一段时间弄清楚为什么我的程序可怕地发生故障,取代了原始的非模板化版本.最后,我意识到编译器不会将模板化版本视为复制构造函数,而是提供默认版本.默认的只是愚蠢地复制内容而不更新计数器,所以我最终得到悬空指针和双重释放.同样的事情适用于赋值运算符.
template<typename T> class CountedPointer { // ... template<U> CountedPointer(const CountedPointer<U> &other); template<typename U> friend class CountedPointer; };