我正在尝试试验五/三/零的规则。编译我的程序时,我收到一条警告 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 ofowner<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/