自定义引用计数指针在创建后立即调用析构函数

如何解决自定义引用计数指针在创建后立即调用析构函数

我目前正在阅读 David H. Eberly 所著的“3D 游戏引擎架构”一书,并决定实现我自己的小引用计数智能指针。我主要遵循他的实施,但我的实施遇到了问题。

我创建了一个名为“CreateRef”的函数,它返回一个指针。当我在与我创建的对象相同的范围内使用这个函数时,一切都很好,但是当我将对象放入全局范围时,它会在创建后立即销毁对象。

class Object
{
public:
    void IncrementReferences()
    {
        ++m_References;
    }
    void DecrementReferences()
    {
        if(--m_References == 0) delete this;
    }
    int GetReferenceCount() const { return m_References; }

private:
    int m_References = 0;
};
template<class T>
class Pointer
{
public:
    //costr and destr
    Pointer(T* pObject = nullptr)
    {
        m_pObject = pObject;
        if (m_pObject)
            m_pObject->IncrementReferences();
    }

    Pointer(const Pointer& rPointer)
    {
        m_pObject = rPointer.m_pObject;
        if (m_pObject)
            m_pObject->IncrementReferences();
    }

    ~Pointer()
    {
        if (m_pObject)
            m_pObject->DecrementReferences();
    }

    // implicit conversions
    operator T* () const
    {
        return m_pObject;
    }
    T& operator* () const
    {
        return *m_pObject;
    }
    T* operator-> () const
    {
        return m_pObject;
    }

    // Assignment
    Pointer& operator= (T* pObject)
    {
        if (m_pObject != pObject)
        {
            if (pObject)
                pObject->IncrementReferences();

            if (m_pObject)
                m_pObject->DecrementReferences();

            m_pObject = pObject;
        }
        return *this;
    }
    Pointer& operator= (const T* rReference)
    {
        if (m_pObject != rReference)
        {
            if (rReference)
                rReference->IncrementReferences();

            if (m_pObject)
                m_pObject->DecrementReferences();

            m_pObject = rReference;
        }
        return *this;
    }

    // Comparisons
    bool operator== (T* pObject) const { return m_pObject == pObject; }
    bool operator!= (T* pObject) const { return m_pObject != pObject; }
    bool operator== (const Pointer& rReference) const { return m_pObject == rReference.m_pObject; }
    bool operator!= (const Pointer& rReference) const { return m_pObject != rReference.m_pObject; }

protected:
    // The shared object
    T* m_pObject;
};
template<typename T>
using Ref = Pointer<T>;

template<typename T,typename ...Args>
constexpr Ref<T> CreateRef(Args&&... args)
{
    return Ref<T>(new T(args...));
}

主要

static Ref<Person> person = nullptr; // Doesn't work like this

static void DoSomething()
{
    person = CreateRef<Person>("Name");
    std::cout << "References " << person->GetReferenceCount() << std::endl;

    Ref<Person> newPerson = person;
    std::cout << "References " << newPerson->GetReferenceCount() << std::endl;
}

int main()
{
    DoSomething();

    std::cout << person->GetReferenceCount();
}

我感觉我在“指针”类中做错了什么,但我不太明白我错过了什么。

解决方法

感谢您的帮助。我找到了两种解决问题的方法。

第一个解决方案是在 Pointer 类中添加一个复制赋值运算符。

Pointer& operator= (Pointer& rPointer)
    {
        if (m_pObject != rPointer.m_pObject)
        {
            if (rPointer)
                rPointer.m_pObject->IncrementReferences();

            if (m_pObject)
                m_pObject->DecrementReferences();

            m_pObject = rPointer.m_pObject;
        }
        return *this;
    }

另一个解决方案(尽管不是我想要的)是将 CreateRef() 函数的返回类型更改为 T*

template<typename T,typename ...Args>
constexpr T* CreateRef(Args&&... args)
{
    return new T(args...);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?