C ++ инициализация const - PullRequest
0 голосов
/ 29 июня 2018

Мне нужно иметь возможность инициализировать константный член внутри конструктора, который подсчитывает каждый раз, когда я создаю новый объект. В школе мне показали, как это работает, но я все время получаю ошибки. Это как-то связано с конструктором копирования.

Вот код и ошибки компилятора:

class kunde {
public:
    kunde(string name, int alter);
    kunde(const kunde& orig);
    ~kunde();
    int GetAlter() const;
    string GetName() const;
    const int GetKnr() const;

private:
    string name;
    int alter;

    const int knr;

    static int cnt;
    static int MaxKnr;
};

int kunde::cnt = 0;
int kunde::MaxKnr = 1000;

kunde::kunde(string name, int alter):knr(MaxKnr++) {
    this->name = name;
    this->alter = alter;
}

kunde::kunde(const kunde& orig):knr(MaxKnr++){
    this->name = orig.name;
    this->alter = orig.alter;
}

kunde::~kunde() {
}

int kunde::GetAlter() const {
    return alter;
}

string kunde::GetName() const {
    return name;
}

const int kunde::GetKnr() const {
    return knr;
}
        main.cpp: In function 'int main(int, char**)':
    main.cpp:35:15: error: use of deleted function 'kunde& kunde::operator=(const kunde&)'
          v[0] = v[1];
               ^
    In file included from main.cpp:17:0:
    kunde.h:19:7: note: 'kunde& kunde::operator=(const kunde&)' is implicitly  deleted because the default definition would be ill-formed:
     class kunde {
           ^~~~~
    kunde.h:19:7: error: non-static const member 'const int kunde::knr', can't use default assignment operator

1 Ответ

0 голосов
/ 29 июня 2018

knr - это номер счета. каждый раз, когда вы создаете объект, он создает новый постоянный номер учетной записи, который остается.

Как указано в комментариях, поскольку knr равно const, компилятор не может сгенерировать назначение копирования по умолчанию operator= для класса, что является именно тем, на что компилятор жалуется для оператора v[0] = v[1];:

примечание: 'kunde & kunde :: operator = (const kunde &)' неявно удаляется, поскольку определение по умолчанию будет некорректным

const элементы не могут быть переназначены после инициализации, поэтому не могут быть скопированы.

Элементы в vector должны быть CopyAssignable и CopyConstructible (по крайней мере до C ++ 11), но ваш класс не имеет жизнеспособной копии -assignment operator=, так что это не CopyAssignable (и это не MoveAssignable в C ++ 11, так как не может быть сгенерировано жизненное назначение Move operator=, либо ).

Решение состоит в том, чтобы реализовать назначение копирования operator= (и, необязательно, назначение перемещения operator=), которое игнорирует knr, например:

class kunde {
public:
    kunde(string name, int alter);
    kunde(const kunde& orig);
    kunde(kunde&& orig);
    ...
    kunde& operator=(const kunde& rhs);
    kunde& operator=(kunde&& rhs);
    ...

private:
    string name;
    int alter;
    const int knr;
    ...
};

kunde::kunde(string name, int alter)
    : knr(MaxKnr++), name(name), alter(alter)
{
}

kunde::kunde(const kunde& orig)
    : knr(MaxKnr++), name(orig.name), alter(orig.alter)
{
}

kunde::kunde(kunde&& orig)
    : knr(MaxKnr++), name(std::move(orig.name)), alter(orig.alter)
{
}

kunde& kunde::operator=(const kunde& rhs)
{
    if (&rhs != this)
    {
        name = rhs.name;
        alter = rhs.alter;
        // CAN'T BE DONE, SO IGNORE IT
        // knr = rhs.knr;
    }
    return *this;
}

kunde& kunde::operator=(kunde&& rhs)
{
    name = std::move(rhs.name);
    alter = rhs.alter;
    // CAN'T BE DONE, SO IGNORE IT
    // knr = rhs.knr;
    return *this;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...