c++ - 实现智能指针 - 使用模板动态分配

标签 c++ smart-pointers

我正在编写智能指针 countedptr,但遇到了障碍。 countedptr 的基本功能是像任何其他智能指针一样工作,并且还计算有多少指针指向单个对象。到目前为止,代码是:

[已解决]

#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; delete pointer; }

    counted_ptr& operator=(const counted_ptr& p)
    {
        pointer = p.pointer;
        count = p.count;
        ++*count;
        return *this;
    }
    T* operator->() const{ return pointer; }
    T& operator*() const { return *pointer; }

    int Get_count() const { return *count; }
};


int main()
{
    counted_ptr<double> one;
    counted_ptr<double>two(one);
    int a = one.Get_count();
    cout << a << endl;
}

当我尝试做类似的事情时

one->pointer = new double(5);

然后我收到一个编译器错误,提示“在'*(&one)->counted_ptr::operator->with T = double'中请求成员'pointer',它是非类类型double”。

我考虑过制作一个函数来执行此操作,虽然我可以制作一个函数来分配 T 的数组,但我想不出一种方法来制作一个用于分配实际对象的函数。感谢任何帮助,谢谢。

最佳答案

旧方案

另一个赋值运算符呢?

counted_ptr& counted_ptr::operator=(T* p)
{
    if (! --*count) { delete count; }
    pointer = p;
    count = new int(1);
    return *this;
}

...

one = new double(5);

此外,您的析构函数总是删除一个共享指针,这可能是导致 *one 成为随机数的原因。也许你想要这样的东西:

counted_ptr::~counted_ptr() { if (! --*count) { delete pointer; delete count; } }

新解决方案

当你想重新指向一个 counted_ptr(例如 one = new double(5))来更新所有相关的 counted_ptr 时,将指针和计数都放在一个 helper 中类,并让您的指针类持有指向辅助类的指针(您可能已经沿着这条路前进)。您可以通过两种方式填写此设计:

  1. 使辅助类成为一个简单的结构(和一个私有(private)内部类)并将所有逻辑放在外部类方法中
  2. 使 counted_ptr 成为辅助类。 counted_ptr 维护引用计数但不会自动更新计数;它不是智能指针,它只响应releaseretain 消息。如果您完全熟悉 Objective-C,这基本上就是它的传统内存管理(autoreleasing 放在一边)。当引用计数达到 0 时,counted_ptr 可能会也可能不会删除自身(与 Obj-C 的另一个潜在差异)。 counted_ptr 不应该是可复制的。目的是对于任何普通指针,最多应该有一个 counted_ptr

    创建一个 smart_ptr 类,它有一个指向 counted_ptr 的指针,它在本应包含相同内容的 smart_ptr 实例之间共享指针。 smart_ptr 负责通过发送其 counted_ptr 释放和保留方法来自动更新计数。

    counted_ptr 可能是也可能不是 shared_ptr 的私有(private)内部类。

这是选项二的界面。由于您将此作为练习进行,因此我会让您填写方法定义。潜在的实现将类似于已经发布的内容,除了您不需要 counted_ptr 的复制构造函数和复制赋值运算符,counted_ptr::~counted_ptr 不调用counted_ptr::release(这是 smart_ptr::~smart_ptr 的工作)并且 counted_ptr::release 可能不会释放 counted_ptr::_pointer(您可以将其留给析构函数)。

// counted_ptr owns its pointer an will free it when appropriate.
template <typename T>
class counted_ptr {
private:
    T *_pointer;
    size_t _count;

    // Make copying illegal
    explicit counted_ptr(const counted_ptr&);
    counted_ptr& operator=(const counted_ptr<T>& p);

public:
    counted_ptr(T* p=0, size_t c=1);
    ~counted_ptr();

    void retain();        // increase reference count.
    bool release();       // decrease reference count. Return true iff count is 0
    void reassign(T *p);  // point to something else.
    size_t count() const;

    counted_ptr& operator=(T* p);

    T& operator*() const;
    T* operator->() const;
};

template <typename T>
class smart_ptr {
private:
    counted_ptr<T> *_shared;
    void release();  // release the shared pointer
    void retain();   // retain the shared pointer

public:
    smart_ptr(T* p=0, int c=1);   // make a smart_ptr that points to p
    explicit smart_ptr(counted_ptr<T>& p); // make a smart_ptr that shares p
    explicit smart_ptr(smart_ptr& p); // copy constructor
    ~smart_ptr();

    // note: a smart_ptr's brethren are the smart_ptrs that share a counted_ptr.
    smart_ptr& operator=(smart_ptr& p); /* Join p's brethren. Doesn't alter pre-call
        * brethren. p is non-const because this->_shared can't be const. */
    smart_ptr& operator=(counted_ptr<T>& p);  /* Share p. Doesn't alter brethren. 
        * p is non-const because *this isn't const. */
    smart_ptr& operator=(T* p); // repoint this pointer. Alters brethren

    size_t count() const; // reference count

    T& operator*() const;  // delegate these to _shared
    T* operator->() const;

};

希望以上唯一含糊不清的地方是故意的。

关于c++ - 实现智能指针 - 使用模板动态分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1314824/

相关文章:

c++ - CComPtr CoCreateInstance 返回 0x80070582(类已存在。)

C++ - 在初始化类成员之前运行一个函数

c++ - 使用两个相同的 typedef 不好吗?如何避免?

c++ - MIPS 语言中的嵌套和递归过程

Mac 上的 C++ 库无法使用 g++ my_program.cpp -o my_program 进行编译

c++ - 无法打开套接字。由 小码哥发布于

c++ - 如何使用 ifstream 和 istreambuf_iterator 将二进制文件读取为 float?

c++ - 根据用户输入创建结构

c++ - 智能指针的计数器递减如何工作?

c++ - 关于 "circular reference",我使用了 weak_ptr 但内存泄漏仍然发生