Референтный член Требуется ли Const? - PullRequest
4 голосов
/ 03 сентября 2010

В этом простом примере, почему мне нужно сделать const для 'member', чтобы компилировать его?

struct ClassA
{
    ClassA(int integer) {}
};

struct ClassB
{
    ClassB(int integer):
        member(integer)
    {
    }

    const ClassA& member;
};

int main()
{
    ClassB* b = new ClassB(12);

    return 0;
}

В противном случае я получаю эту ошибку:

ошибка: неверная инициализация ссылка типа "ClassA &" из выражение типа 'int'

Ответы [ 4 ]

10 голосов
/ 03 сентября 2010

Причина в том, что на самом деле здесь происходит то, что вы используете неявное преобразование из int в ClassA при инициализации member. В развернутом виде это фактически делает следующее

member(ClassA(integer))

Это означает, что экземпляр ClassA является временным. Недопустимо иметь ссылку на временную переменную только на константную, поэтому вы получаете ошибку компилятора.

Самое простое решение - удалить модификатор & на элементе и сделать его просто типа ClassA

ClassA member;

Кроме того, хорошей практикой является размещение explicit перед конструктором ClassA, чтобы избежать неявного неявного преобразования.

explicit ClassA(int integer){}
4 голосов
/ 03 сентября 2010

Поскольку вы пытаетесь сохранить ссылку на временный объект, и вы можете хранить только постоянные ссылки на временные объекты.

Когда вы пытаетесь инициализировать ссылку member типа ClassA& с параметром integer типа int, конструктор неявного преобразования ClassA::ClassA(int integer) запрашивает создание неназванного временного объекта типа ClassA из переменной integer. Этот безымянный временный объект затем используется для инициализации ссылки member, создавая ссылку на временный объект, который должен быть постоянным.

Я подвергаю сомнению ваш дизайн здесь. Если вы пытаетесь инициализировать member с данными, передаваемыми по значению конструктору ClassB, иметь ссылку member в качестве ссылки, вероятно, неправильно. Как вы думаете, почему member должен быть ссылкой, а не просто объектом?

0 голосов
/ 03 сентября 2010

Вы создаете временное и инициализируете ссылку из этого временного.Точно так же, как обычно, чтобы связать с временным, ссылка должна быть константой.

У меня были бы серьезные вторые мысли об этом.Класс со ссылочным членом редко бывает полезен.Когда это полезно, вы обычно хотите начать с некоторого существующего объекта и передать ссылку на этот объект через ссылку на член.Когда вы сделаете это, вам понадобится , чтобы убедиться, что указанный объект существует в течение всего времени существования объекта, содержащего ссылку, поэтому эти два элемента довольно тесно связаны, чтообычно лучше избегать.

0 голосов
/ 03 сентября 2010

ClassA является эталонным членом ClassB, поэтому его необходимо создать с экземпляром ClassA.

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