实现智能指针 - 在向量中存储模板类

时间:2009-08-22 18:01:47

标签: c++ smart-pointers

我无法将智能指针的实例存储到容器中。这是指针的代码。

#include "std_lib_facilities.h"

template <class T>
class counted_ptr{
private:
    T* pointer;
    int* count;

public:
    counted_ptr(T* p = 0, int* c = new int(1)) : pointer(p), count(c) {}    // default constructor
    explicit counted_ptr(const counted_ptr& p) : pointer(p.pointer), count(p.count) { ++*count; } // copy constructor
    ~counted_ptr()
    {
        --*count;
        if(!*count) {
            delete pointer;
            delete count;
        }
    }

    counted_ptr& operator=(const counted_ptr& p)    // copy assignment
    {
        pointer = p.pointer;
        count = p.count;
        ++*count;
        return *this;
    }
    T* operator->() const{ return pointer; }
    T& operator*() const { return *pointer; }
    int& operator[](int index) { return pointer[index]; }

    int Get_count() const { return *count; }    // public accessor for count


};




int main()
{
    counted_ptr<double>one;
    counted_ptr<double>two(one);
    one = new double(5);
    vector<counted_ptr<double> >test;
}

在int main()中,vector<counted_ptr<double> >行会编译。当我第一次尝试使用vector<counted_ptr<double> >时,它没有编译(可能是因为它缺少参数。)但是,当我尝试使用push_back时,如

test.push_back(one);

我收到编译错误,打开了vector.tcc,并指出了

的特定错误
no matching function for call to `counted_ptr<double>::counted_ptr(const counted_ptr<double>&)'|

我猜push_back无法找到counting_ptr,但我真的不确定。任何  非常感谢,谢谢。

编辑:但是,这有效。 test [0] = 1;我猜push_back的语义是限制它的。

2 个答案:

答案 0 :(得分:5)

你可能想试试这个:

test.push_back(counted_ptr<double>(one));

复制构造函数是显式的,这意味着编译器不会隐式调用它。

就个人而言,我会使原始指针构造函数显式,并且复制ctor不显式。这将更接近通常的行为。

编辑:我还建议你实现一个交换方法。它使作业绝对无足轻重。你最终得到这样的东西:

counted_ptr &operator=(const counted_ptr &rhs) {
    counted_ptr(rhs).swap(*this);
    return *this;
}

这也有构造函数/析构函数中发生的会计所有的好处,管理起来要简单得多: - )。

答案 1 :(得分:2)

你的任务操作员错了。
它指向的物体发生了什么事? 如果您分配给自​​己或同一内部对象会发生什么?

counted_ptr& operator=(const counted_ptr& p)    // copy assignment
{
    if (&p != this)
    {
        --*count;
        if ((*count) == 0) // Much more readable than !*count
        {
            delete pointer;
            delete count;
        }
        pointer = p.pointer;
        count = p.count;
        ++*count;
    }
    return *this;
}

注意:编写自己的智能指针不是一个好主意。       他们写作并不像你想象的那么简单。

注意:这是我发现的第一件事。可能会有更多,我不确定这是100%正确。

实际上我会将赋值运算符更改为使用copy / swap idium。

counted_ptr& operator=(const counted_ptr& p)    // copy assignment
{
    counted_ptr<T>     tmp(p);   // increment counter on p
    swap(tmp.pointer, pointer);
    swap(tmp.count    count);

    return *this;
                                 // tmp goes out of scope and thus the
                                 // destructor gets called and what was in this
                                 // object is now destroyed correctly.
}
// It may even be worth writing your own swap operator.
// Make sure you declare it as no-throw and grantee it.