按照网上教程中关于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)))
参数传递给父级。
有什么方法可以更清晰、更正确地编写相同的代码?