С++ Правило 5 с реализацией наследования
Следуя примерам из онлайн-руководств по правилам 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? Меня не очень убеждает прямое использование операторов (
Есть ли способ написать тот же код более четко и правильно?