Как работать с двойными (или множественными) конструкторами копирования для класса с указателями - PullRequest
0 голосов
/ 24 мая 2018

Существует класс с именем "X", подобный следующему:

class X {
private:
    int *ptr;
public:
    X() {
        ptr = new int[2];
        ptr[0] = 0;
        ptr[1] = 0;
    }
    X(int a, int b) {
        ptr = new int[2];
        ptr[0] = a;
        ptr[1] = b;
    }
    X(const X &val) {
        delete[] ptr;
        ptr = new int[2];
        ptr[0] = val.ptr[0];
        ptr[1] = val.ptr[1];
    }
    X get() {
        X ret(ptr[0], ptr[1]);
        return ret;
    }
};

Предположим, что существует переменная X, определенная с помощью X v(2, 3).

Если мы вызываем v.get(),это нормально.

Но, если мы позвоним v.get().get(), это не хорошо.Он выдает ошибку времени выполнения в секции delete[] ptr в конструкторе копирования, содержание которого заключается в том, что я пытаюсь удалить неопределенный (0xcccccccc) указатель.

Один из возможных вариантов решения этой проблемы - использование C ++ - STL.как <array> или <vector>.Но я хочу реализовать с помощью указателя.

Как справиться с этой ошибкой во время выполнения, с реализацией на основе указателя?

1 Ответ

0 голосов
/ 24 мая 2018

Простой ответ заключается в том, что вы не должны delete[] ptr в конструкторе копирования, потому что он не инициализирован.Вам не нужно delete[] ptr в назначении, либо. только место delete или delete[] должно произойти в деструкторе.

Уборка вашего класса, не переходя от владения необработанными указателями

class X {
private:
    int *ptr;
public:
    X() : X(0, 0) { }
    X(int a, int b) : ptr(new int[2]) {
        ptr[0] = a;
        ptr[1] = b;
    }
    X(const X &val) : X(val.ptr[0], val.ptr[1]) { }
    X& operator=(const X &val)
    {
        ptr[0] = val.ptr[0];
        ptr[1] = val.ptr[1];
        return *this;
    }
    X(X&& val) : ptr(val.ptr) {
        val.ptr = nullptr;
    }
    X& operator=(X&& val) {
        std::swap(ptr, val.ptr);
        return *this;
    }        
    ~X() { delete[] ptr; }

    X get() {
        return *this;
    }
};

AsС точки зрения номенклатуры, конструктор является « копирующим конструктором », только если он принимает экземпляр класса в качестве единственного (не по умолчанию) параметра.X::X(int, int) это просто конструктор.Это означает, что существует не более 4 конструкторов копирования (в противном случае они будут неоднозначными при разрешении перегрузки)

X::X(X &)
X::X(const X &)
X::X(volatile X &)
X::X(const volatile X &)

Однако определение более одного - ужасная идея, если только вы не участвуете в конкурсе запутывания

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...