编写智能指针的复制构造函数的问题 [英] Problems writing a copy constructor for a smart pointer

查看:333
本文介绍了编写智能指针的复制构造函数的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的代码有自己的智能指针实现,它做简单的引用计数。是的,我们不应该有自己的实现。是的,我们应该使用一个从boost或一些这样。与我一起。



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

  ... 
CountedPointer< Base>基础;
...
CountedPointer< Derived>派生;
...
base = derived;但是,CountedPointer的拷贝构造函数有一个这样的原型:



  CountedPointer(const CountedPointer< T>& other); 

所以上面的代码不会编译,因为它找不到合适的构造函数 - 这是同一个故事)。我试着用这样的原型重写复制构造函数:

  template< U> 
CountedPointer(const CountedPointer< U>& other);然而,我碰到的问题是,复制构造函数必须访问它复制的对象的私有成员($($)



<



Alexandrescu在他的库中避免了这个问题 Loki 通过为封装的指针提供访问器函数,但我不想直接访问原始指针,如果可能。 p>

有没有办法我可以写这个来允许派生的基本副本,但不允许一般访问原始指针?



更新:
我已经实现了下面接受的答案,它工作正常。我花了一段时间想知道为什么我的程序seg-faulted可怕,当我只提供模板版本的副本构造函数,替换原来的非模板化版本。最终,我意识到编译器不把模板版本作为一个复制构造函数,并提供一个默认的。默认的只是愚蠢的复制内容,而不更新计数器,所以我最终得到悬挂指针和双释放。

解决方案

不能让他们成为朋友吗?喜欢:

 模板< typename T& 
class CountedPointer {

// ...

模板< U>
CountedPointer(const CountedPointer< U>& other);

template< typename U>朋友类CountedPointer;
};


The code I'm working with has its own smart pointer implementation which does simple reference counting. Yes, we shouldn't have our own implementation. Yes, we should be using one from boost or some such. Bear with me.

I found I wanted to write code like this:

...
CountedPointer<Base> base;
...
CountedPointer<Derived> derived;
...
base = derived;

However, the copy constructor for CountedPointer has a prototype like this:

CountedPointer(const CountedPointer<T> &other);

So the above code won't compile since it can't find a suitable constructor (or assignment operator - it's the same story there). I tried re-writing the copy constructor with a prototype like this:

template<U>
CountedPointer(const CountedPointer<U> &other);

However, I hit the problem that the copy constructor must access a private member of the object it's copying (i.e. the raw pointer) and if it's in a different specialisation of CountedPointer, they're not visible.

Alexandrescu avoids this problem in his library Loki by having accessor functions for the encapsulated pointer, but I'd prefer not to give direct access to the raw pointer if possible.

Is there any way I can write this to allow the derived to base copy, but not allow general access to the raw pointer?

Update: I've implemented the accepted answer below, and it works well. I spent a while figuring out why my program seg-faulted horribly when I only provided the templated version of the copy constructor, replacing the original un-templated version. Eventually, I realised that the compiler doesn't regard the templated version as being a copy constructor, and provides a default one. The default one just dumbly copies the contents without updating the counter, so I end up with dangling pointers and double frees. The same sort of thing applies to the assignment operator.

解决方案

Can't you make them friends? Like:

template<typename T>
class CountedPointer {

    // ...

    template<U>
    CountedPointer(const CountedPointer<U> &other);

    template<typename U> friend class CountedPointer;
};

这篇关于编写智能指针的复制构造函数的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆