【问题标题】:Destructor for pointer and non pointer指针和非指针的析构函数
【发布时间】:2021-11-28 07:56:45
【问题描述】:

为什么这行不通。有没有办法做到这一点? 我不想为指针创建单独的函数

#include <iostream>

using namespace std;

template<class T>
class temp
{
public:
  T val;

  temp(T value) : val(value) {}
  ~temp()
  {
    if(is_pointer<T>::value)
    {
      delete val;
    }
  }

};


int main()
{
  string * n = new string("cat");

  temp<string*>object(n);//ok

  temp<string>object2("dog"); //compliation error: type 'class std::cxx11::basic_string' argument given to 'delete', expected pointer. --- (but there is if statement!!!!)
  //i dont want delete in main

  return 0;
}

要编译,我使用 g++ 6.3.0 有人可以帮忙吗?也许,我需要将声明与定义分开?

【问题讨论】:

  • 请提供更多信息,如配置、编译器、C++ 版本、错误详情和实际问题。
  • 从技术上讲,您的temp 类并不拥有指针或它指向的数据的所有权。所以它不应该尝试delete它。
  • 永恒的基本规则是:delete 你用new 创建的,delete[] 你用new[] 创建的。如果您将指针传递给temp,您仍然不能确定它是否可以是deleted 而不会导致未定义行为。想象一下,我将您的temp&lt;int*&gt; 用于int i; temp&lt;int*&gt; tI(&amp;i);...
  • new string("cat") 是代码异味,不在main 中删除它只会让它变得更糟。你能解释一下目标是什么吗?为什么不temp&lt;string&gt;?或者如果你坚持动态分配temp&lt; std::unique_ptr&lt;std::string&gt;&gt;
  • 使用 C++17 if constexpr (is_pointer&lt;T&gt;::value) 将允许它编译(尽管它仍然会有其他评论者提到的问题)

标签: c++ pointers templates destructor dynamic-memory-allocation


【解决方案1】:

您遇到的问题是if 的分支必须始终在语法上有效,即使它从未被采用。

可以使用if constexpr,这是一个“编译时间如果”

~temp()
  {
    if constexpr(is_pointer<T>::value)
    {
      delete val;
    }
  }

然而这并不安全。

您怎么知道传递给temp&lt;T*&gt; 的指针是由new 而不是new[]malloc 或通过获取非动态分配的对象的地址创建的?

与其假设应该删除指针,不如避免知道要删除哪些指针

#include <string>
#include <memory>

template<class T>
class temp
{
public:
  T val;

  temp(T value) : val(value) {}

  // n.b. no need to define destructor
};

int main()
{
  std::string str("cat");
  temp<std::string*> object(&str);//ok

  temp<std::string> object2("dog"); // also ok

  std::unique_ptr<std::string> str2 = std::make_unique<std::string>("mouse");
  temp<std::string *> object3(str2.get()); // ok so long as str2 outlives object3

  std::shared_ptr<std::string> str3 = std::make_shared<std::string>("rabbit");
  temp<std::shared_ptr<std::string>> object4(str3); // also ok

  return 0;
}

【讨论】:

  • 你建议不要在析构函数中使用delete?不确定我是否理解答案,因为您修复了constexprtemp&lt;std::string*&gt; object(&amp;str); 不是“好的”
  • @463035818_is_not_a_number 确实
猜你喜欢
  • 2022-01-20
  • 2022-01-01
  • 2021-07-25
  • 1970-01-01
  • 2012-04-17
  • 2015-12-05
  • 2011-12-13
  • 2012-01-22
  • 1970-01-01
相关资源
最近更新 更多