我正在使用的代码有它自己的智能指针实现,它可以进行简单的引用计数。是的,我们不应该有自己的实现。是的,我们应该使用来自 boost 的一个或类似的。请耐心等待。
我发现我想写这样的代码:
...
CountedPointer<Base> base;
...
CountedPointer<Derived> derived;
...
base = derived;
但是,CountedPointer 的复制构造函数具有如下原型(prototype):
CountedPointer(const CountedPointer<T> &other);
所以上面的代码将无法编译,因为它找不到合适的构造函数(或赋值运算符 - 这是同样的故事)。我尝试用这样的原型(prototype)重写复制构造函数:
template<U>
CountedPointer(const CountedPointer<U> &other);
但是,我遇到了复制构造函数必须访问它正在复制的对象的私有(private)成员(即原始指针)的问题,如果它在 CountedPointer 的不同特化中,它们是不可见的。
Alexandrescu 在他的图书馆中避免了这个问题 Loki通过为封装指针提供访问函数,但如果可能,我不希望直接访问原始指针。
有什么方法可以让我将派生对象复制到基础拷贝,但不允许对原始指针进行一般访问?
更新: 我已经在下面实现了接受的答案,并且效果很好。我花了一段时间弄清楚为什么当我只提供复制构造函数的模板化版本,替换原始的非模板化版本时,我的程序会出现可怕的段错误。最终,我意识到编译器并不将模板化版本视为复制构造函数,而是提供了一个默认版本。默认的只是愚蠢地复制内容而不更新计数器,所以我最终得到了悬空指针和双重释放。同样的事情也适用于赋值运算符。
最佳答案
你不能让他们成为 friend 吗?喜欢:
template<typename T>
class CountedPointer {
// ...
template<U>
CountedPointer(const CountedPointer<U> &other);
template<typename U> friend class CountedPointer;
};
关于c++ - 为智能指针编写复制构造函数的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/561115/