2010-11-15 3 views
3

Скажем класса содержит ссылку под названием matrix_:Как инициализировать ссылку на объект, если ссылка является членом класса?

Class.h

class Class 
{ 
Matrix& matrix_; 
} 

Class.cpp

Class::Class() : matrix_(Matrix()) 
{ 
} 

Я получаю сообщение об ошибке: недопустимый инициализацию неконстантных ссылка типа «Матрица &» от временного типа «Матрица».

Я вижу, что проблема в том, что временный объект исчезнет, ​​а ссылка укажет на NULL. Как создать постоянный объект для ссылки? Я хочу использовать ссылку, потому что этот член должен быть постоянным.

+0

вы не можете связывать RValue с неконстантной ссылкой – erjot

ответ

5

Class::Class() : matrix_(Matrix()) пытается установить ссылку, чтобы указать на временный объект, который является незаконным.

хорошо, есть случай со ссылками на const и временная привязка, но серьезно, не туда.

Похоже, вам просто нужно использовать агрегацию:

class Class 
{ 
const Matrix matrix_; 
}; 

И список инициализатора:

Class::Class() : matrix_() /* or any params to the constructor if you need them */ 
{ 
} 
+1

+1 для поддержания простоты :) Возможно, вы захотите добавить полуточку после определения класса (я бы сделал это для вас, но недостаточно rep). Похож на распространенную ошибку из исходного вопроса ... –

+0

Я забыл, что могу сделать это так просто. – problemofficer

+1

@sgolodetz, Совершенно верно, я исправлю это сразу, просто для ясности. :) – Kos

1

Проблема в том, что ссылки не предназначены для использования. Они должны использоваться больше как «псевдоним» для уже существующего. Будь то анонимный объект стека (жизнь которого контролируется областью кодов) или объект кучи со своим уже существующим указателем. В вашем случае вы пытаетесь использовать ссылку только для своего свойства константы, но забываете, что это больше, чем постоянный указатель.

Соответствующее решение было бы использовать постоянный указатель и выделить новый объект в куче, как это:

Class.h

class Class 
{ 
Matrix* const matrix_; 
} 

Class.cpp

Class::Class() : matrix_(new Matrix()) 
{ 
} 
+0

я ответил на свой вопрос, потому что он пришел ко мне, задумавшись над вопросом, и я хотел поделиться этим с другими, столкнувшимися с одной и той же проблемой. Я не уверен, что это правда. – problemofficer

+5

Или просто создайте его как ценность и забудьте о косвенности. –

3

В Ссылка на матрицу должна быть представлена ​​как аргумент всех конструкторов класса.

class Class 
{ 
    Matrix & matrix_; 
public: 
    Class(Matrix & matrix); 
}; 

Class::Class(Matrix & matrix) : matrix_(matrix) 
{ 
} 

Обратите внимание, что, хотя ссылка будет постоянной (ссылки на C++ являются постоянными указателями), упоминаемая матрица не будет, если вы добавите константный спецификатор.

+0

matrix_ является приватным, так что это не вариант ufortood – problemofficer

1

Вам не обязательно использовать ссылку для того, чтобы этот член был постоянным. Вы можете использовать boost::scoped_ptr<const Matrix>.

class Class 
{ 
public: 
    Class(); 
private: 
    boost::scoped_ptr<const Matrix> _matrix; 
} 

Class::Class() : _matrix(new Matrix) 
{ 
} 
+0

Мне любопытно, почему вы предлагаете boost :: scoped_ptr вместо std :: auto_ptr? – Flexo

+0

@awoodland - чисто привычка, я редко использую 'auto_ptr' –

+0

Я был обеспокоен тем, что была какая-то веская причина, чтобы поддержать его по сравнению с auto_ptr, которого я не заметил раньше – Flexo

Смежные вопросы