提问人:Andrea 提问时间:9/6/2021 最后编辑:Zoe is on strikeAndrea 更新时间:9/6/2021 访问量:250
具有继承实现的 C++ 5 法则
C++ Rule of 5 with inheritance implementation
问:
按照在线教程中关于 5 规则的示例,我编写了以下课程:
#include <iostream>
#include <cstring>
#include <utility>
class A2
{
char* _buff;
public:
A2(const char *text = "test") {
std::cout << "New A2\n";
_buff = new char[256];
size_t length = strnlen(text, 255) + 1;
strncpy(_buff, text, length);
}
virtual ~A2() {
std::cout << "Delete A2\n";
delete[] _buff; // deallocate
}
A2(const A2& other) : A2(other._buff) {
std::cout << "Copy constructor A2\n";
}
A2(A2&& other) noexcept : _buff(std::exchange(other._buff, nullptr)) {
std::cout << "Move constructor A2\n";
}
A2& operator=(const A2& other) {
std::cout << "Copy assignment A2\n";
return *this = A2(other);
}
A2& operator=(A2&& other) noexcept {
std::cout << "Move assignment A2\n";
std::swap(_buff, other._buff);
return *this;
}
};
做一些测试,它实际上似乎对我有用(它是通过示例中的一些自定义项复制的)。
因此,我尝试创建一个继承自 A2 的类(在这种情况下,作为构造函数参数的文本也传递给父级,但在它们的内部管理中它们保持独立):
class B2 final : public A2
{
char* _buff2;
public:
B2(const char* text) : A2(text) {
_buff2 = new char[256];
size_t length = strnlen(text, 255) + 1;
strncpy(_buff2, text, length);
std::cout << "new B2\n";
}
~B2() {
std::cout << "delete B2\n";
delete[] _buff2; // deallocate
}
B2(const B2& other) : A2(other) {
_buff2 = new char[256];
size_t length = strnlen(other._buff2, 255) + 1;
strncpy(_buff2, other._buff2, length);
std::cout << "copy constructor B2\n";
}
B2(B2&& other) noexcept : A2(static_cast<A2&&>(other)), _buff2(std::exchange(other._buff2, nullptr))
{
std::cout << "move constructor B2\n";
}
B2& operator=(const B2& other) {
std::cout << "operator = in B2\n";
A2::operator= (other);
size_t length = strnlen(other._buff2, 255) + 1;
strncpy(_buff2, other._buff2, length);
return *this;
}
B2& operator=(B2&& other) noexcept {
std::cout << "move assignment B2\n";
A2::operator=(static_cast<A2&&>(other));
std::swap(_buff2, other._buff2);
return *this;
}
};
它似乎工作正常(我也在这里做了一些测试,并检查调试器是否一切正常)。
但我的疑问是:为 B2 类写的是正确的吗?我不太相信直接使用运算符 ( 并将参数传递给父级。A2::operator = (other)
A2::operator = (static_cast <A2&&> (other)))
有没有办法更清晰、更正确地编写相同的代码?
答: 暂无答案
下一个:使用多态性时的五法则
评论
A2(static_cast<A2&&>(other))
最好写成 - 另外,为什么不分配同样多的内存呢? 和A2(std::move(other))
A2(const char* text, size_t len) : len_(len), buff_(new char[len_ + 1]) { std::copy_n(text, len_ + 1, _buff); }
A2(const char* text = "test") : A2(text, std::strlen(text)) {}
Is there any way to write the same code more clearly and correctly?
使用 instead of 会使很多事情变得更容易。当你使用它时,它表明它是一个字符串,所以使用可能是更好的选择?(当然,如果你想学习这个,这并不能回答如何正确地执行五法则,但一般来说,你想把容易出错的工作转移到编译器和std上)std::vector<char>
char *
strncpy
std::string
std::string