【问题标题】:Triggered a breakpoint (Destructor) with class template type is a version of itself?触发断点(析构函数)的类模板类型是它自己的一个版本?
【发布时间】:2018-09-02 04:10:38
【问题描述】:

这样的类:

template <class Type>
class test {
    Type* ptr;
public:
    test() {
        ptr = new Type;
    }
    test(int x) {
        ptr = new int;
        *ptr = x;
    }
    test(const test<Type>& other) {
        ptr = new Type;
        *ptr = *other.ptr;
    }
    ~test() {
        delete ptr;
        cout << "Deleted " << typeid(test<Type>).name() << endl;
    }

    Type& getptr () {
        return *ptr;
    }
};

并使用它:

int main() {
    test<int> a = 5;     // This seems to be fine
    test<int> c = a;     // This seems to be fine
    test<test<int>> b;
    b.getptr() = a;      // This seems fine to me

    cout << b.getptr().getptr() << endl;  // This worked (Printed 5)

    return 0;
}

然后在该行触发断点

delete ptr;

当我删除该行时(因为我知道它会导致错误但我不知道为什么)

 b.getptr() = a;

或者改成

 b.getptr().getptr() = 5;

一切正常。


那为什么我使用的时候会触发断点

 b.getptr() = a;

但是

test<int> c = a;
b.getptr().getptr() = 5;

两者都有效?它们是否与“b.getptr()”相同,返回对 *(b.ptr) 的引用,这与上面的行相同并且它们都具有相同的类型“test”? (我也测试过)

cout << typeid(b.getptr()).name() << endl; // Print "class test<int>"



而且,与

b.getptr() = a;

它仍然打印正确的输出。 有人可以解释我做错了什么或错过了什么吗?我已经尝试自己寻找答案,但我仍然无法理解问题所在,也无法找到解决方法。 谢谢。



对不起我糟糕的英语,也因为我找不到更好的方式来更好地在标题中描述我的问题。

【问题讨论】:

  • 我想你的意图不是test(int x) { ptr = new int; *ptr = x; },而是test(Type x) { ptr = new Type; *ptr = x; }
  • 你可能想看看rule of 5/3/0
  • @AlgirdasPreidžius 确实如此,“test(const test& other)”这不是复制构造函数吗?如上所述,“test c = a;”也不会导致任何崩溃(当我删除我怀疑一切正常的行时)
  • @G.M.谢谢,一切都解决了
  • @TríTrầnMinh - 是的:你已经完成了一个复制构造函数;但您还需要一个明确的operator=(test&lt;Type&gt; const &amp;);当您编写 b.getptr() = a; 时,它不是复制构造函数,而是 operator=() 起作用。

标签: c++ class templates destructor


【解决方案1】:

指令后

b.getptr() = a;

ab 都包含指向相同分配值的指针。

这是因为b.getptr() 返回一个对托管(*ptr) 的引用,即test&lt;int&gt;,并在其中复制a 你在a 中复制ptr(*ptr).ptr 中。

所以,在main() 的末尾,你删除了两次相同的分配内存:崩溃!

嗯...不能保证崩溃(您有未定义的行为),但通常您会遇到崩溃。 (感谢 Algirdas Preidžius 指出)

当您直接管理分配的内存时,您需要复制构造函数并且您需要定义一个operator=() 以避免此类问题。 从 C++11 开始,您还需要一个移动构造函数和一个接收正确引用的 operator=()

【讨论】:

  • "你删除了两次相同的分配内存:崩溃" 从技术上讲,双重删除的行为是未定义的行为。如果您“幸运”,您只会遇到崩溃。
  • @AlgirdasPreidžius - 我经常很“幸运” :( 。但你是对的;答案得到改善。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
相关资源
最近更新 更多