当前位置 : 主页 > 编程语言 > c++ >

c – 为智能指针编写复制构造函数的问题

来源:互联网 收集:自由互联 发布时间:2021-06-23
我正在使用的代码有自己的智能指针实现,它可以进行简单的引用计数.是的,我们不应该有自己的实施.是的,我们应该使用boost或者其中之一.忍受我. 我发现我想编写这样的代码: ...Coun
我正在使用的代码有自己的智能指针实现,它可以进行简单的引用计数.是的,我们不应该有自己的实施.是的,我们应该使用boost或者其中之一.忍受我.

我发现我想编写这样的代码:

...
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;
};
网友评论