gpt4 book ai didi

c++ - 没有调用模板类的复制构造函数

转载 作者:太空宇宙 更新时间:2023-11-04 13:55:12 29 4
gpt4 key购买 nike

我正在尝试编写一个示例代码来实现共享指针 [只是为了练习]。在下面的示例中,

  • 为什么编译器不提示修改 other_T
  • 为什么复制构造函数 SharedPtr(const T& other_T) 没有被调用?这是代码片段。

    #include <iostream>
    using namespace std;
    #define DBG cout<<"[DEBUG]"<<__PRETTY_FUNCTION__<<endl
    class RefCount
    {
    protected:
    int m_ref;
    RefCount(){ DBG; m_ref = 1 ; }
    void reference(){ DBG; ++m_ref; }
    void dereference(){ DBG;--m_ref; }
    };

    template <class T>
    class SharedPtr : public RefCount
    {
    T* m_T;
    public:
    SharedPtr() { DBG; m_T = new T; }
    SharedPtr(const T& other_T){
    DBG;
    m_T = other_T.m_T;
    other_T.dereference();
    other_T.m_T = NULL;
    }
    ~SharedPtr() {
    DBG;
    dereference();
    cout<<m_ref<<endl;
    if(m_ref <= 0 && m_T != NULL ){
    cout<<"Destroying"<<endl;
    delete m_T;
    m_T = NULL;
    }
    }
    };

    class A{};
    int main()
    {
    SharedPtr<A> obj;
    cout<<"assigning "<<endl;
    SharedPtr<A> obj2 = obj;
    cout<<"END"<<endl;
    return 0;
    }

结果是段错误。

最佳答案

您的主要问题是复制构造函数正在被调用——但是您还没有定义复制构造函数,所以您得到的是编译器默认定义的复制构造函数。

那个复制构造函数只是做一个成员明智的复制。这意味着您已经为 new 分配了一个 A,然后将两个 SharedPtr 对象指向同一个 A。第一个被销毁的对象删除了 A 对象。然后第二个被销毁,试图再次删除同一个对象,随后发生了严重破坏。

最后,在我看来,这不会产生任何真正的影响。我很确定您的基本设计已损坏。要获得一个有效的共享指针,您需要一个引用计数和指向最终对象的“原始”指针。然后你有 N 个 SharedPtr 对象引用那个引用计数/指针结构,而这个引用计数/指针结构又引用最终对象。

您正在尝试将原始指针/引用计数合并到单独的 SharedPtr 中,但我看不出有任何实际可行的方法。

在我看来,您所谓的 RefCount 的基本概念实际上也是 SharedPtr 设计的一部分。因此,我认为它的定义应该嵌套在 SharedPtr 的定义中(并且可能是私有(private)的,因为外界没有理由知道它的存在,更不用说能够直接访问它了)。

考虑到这些因素,代码最终可能会是这样的:

#include <iostream>
using namespace std;

#define DBG cout<<"[DEBUG]"<<__PRETTY_FUNCTION__<<endl

template <class T>
class SharedPtr {

template <class U>
struct Ref {
mutable int m_ref;
U *data;
Ref(T *data) : m_ref(1), data(data) { DBG; }
void add_ref() const { DBG; ++m_ref; std::cout << "m_ref=" << m_ref << "\n"; }
void sub_ref() const { DBG; --m_ref; std::cout << "m_ref=" << m_ref << "\n"; }
~Ref() { delete data; }
};

Ref<T> *r;
public:
SharedPtr(T *data) { DBG; r = new Ref<T>(data); }
SharedPtr(SharedPtr const &p) : r(p.r) { DBG; r->add_ref(); }
~SharedPtr() {
DBG;
r->sub_ref();
if (0 == r->m_ref) {
delete r;
std::cout << "deleted pointee\n";
}
}
};

class A{};

int main() {
SharedPtr<A> obj(new A);
cout<<"copying "<<endl;
SharedPtr<A> obj2 = obj;
cout<<"END"<<endl;
return 0;
}

注意:虽然这至少修复了一些基本设计,但仍远未可用。它缺少取消引用运算符,因此您不能使用指针来获取它指向的值。它会在多线程环境中完全崩溃。我还没有充分考虑它来确定,但我的直接猜测是它可能也不是异常安全的。

关于c++ - 没有调用模板类的复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21794207/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com