c++ - 不要删除不是 owner<T> 的原始指针 (i.11)

标签 c++ move-semantics

我正在尝试试验五/三/零的规则。编译我的程序时,我收到一条警告 C26401,说我不能删除我不拥有的指针,这在析构函数的 delete[] pChar_; 行中功能。

我同意我在调用 move ctor 时特别遇到问题,当我在调用源对象时应用 std::swap 时。

那么我该如何解决这个问题呢?

编辑:正如评论中所建议的,我可以使用 std::string (好)但我想知道如何在不修改类型的情况下解决问题让我们说要学习:)

using namespace std;

struct A
{

  A();
  A(int Int, const char* pChar);

  A(const A& rhs);
  A& operator=(A rhs);

  A(A&& rhs);

  ~A();

  void swap(A& rhs);
  int Int_ = 0;
  char *pChar_ = nullptr;
};

A::~A()
{
    std::cout << "----DTOR----" << std::endl;

    if (pChar_ != nullptr)
    {
        delete[] pChar_;
        pChar_ = nullptr;
    }
}

A::A(int Int, const char* pChar) :
     Int_(Int), pChar_(new char[strlen(pChar) + 1])
{
    strncpy_s(pChar_, strlen(pChar) + 1, pChar, _TRUNCATE);
}

A::A(const A& rhs) : A(rhs.Int_, rhs.pChar_) {}

A& A::operator=(A rhs)
{   
    swap(rhs);
    return *this;
}

A::A(A&& rhs)
{
    swap(rhs);
}

void A::swap(A& rhs)    
{
    std::swap(this->Int_, rhs.Int_);
    std::swap(this->pChar_, rhs.pChar_);
}

int main()
{
    A v1{ 1, "Hello" }; 
    {
        A v3{ std::move(v1) };
    }
}

最佳答案

我手边没有可以重现您的警告的 VS 拷贝,但在我看来,该警告来自 CPP Code Guidelines , 具体来说 I.11: Never transfer ownership by a raw pointer (T*) or reference (T&) :

Enforcement

  • (Simple) Warn on delete of a raw pointer that is not an owner<T>. Suggest use of standard-library resource handle or use of owner<T>.

所以解决方案是使用gsl::owner<char *> pChar_ = nullptr; .请注意 gsl::owner只不过是帮助代码读者(人类或工具)的注释,不会神奇地使您的代码安全。

据我所知,您的代码看起来还不错。


我遇到的一个问题是 ctor:

A(int Int, const char* pChar) :
    Int_(Int), pChar_(new char[strlen(pChar) + 1])
{
    strncpy_s(pChar_, strlen(pChar) + 1, pChar, _TRUNCATE);
}

这是伪装成安全代码的不安全代码。 strncpy_s给你安全感。但实际上它在您的代码中绝对没有任何作用(为了安全)。因为如果 pChar 有问题(例如,它不指向空终止字符串)然后 strlen会先失败。所以要么说出每个标准函数所说的:pChar应是指向空终止字符串的有效指针,否则算作 UB,或在 strlen 处守卫.一旦你守卫在 strlen 然后 strcpy就够了。

而且你不检查 Int等于strlen .他们应该是。

关于c++ - 不要删除不是 owner<T> 的原始指针 (i.11),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53123829/

相关文章:

c++ - glibc : Test if lib as DF_1_NODELETE flag or if lib has unique symbol

c++ - ifstream 在一个类中

c++ - 生成的复制和 move 运算符?

c++ - 编译器会在 setter 方法中自动应用 move 语义吗?

c++ - unique_ptr 的 move 语义

c++11 - 强制复制构造函数

c++ - Effective Modern C++ 书中 ThreadRAII 的实现是否正确?

c++ - 如何在opengl中翻译屏幕中的投影对象

c++ - 为什么 std::move 不在默认 move 构造函数中将源变量更改为默认值?

c++ - C++ 模板只是变相的宏吗?