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

Есть ли способ написать тот же код более четко и правильно?

0 ответов

Другие вопросы по тегам