2012-07-01 2 views
3

У меня есть следующий код:Как вы явно инициализируете ссылку в C++?

class SomeClass {}; 

class SomeOtherClass { 
    SomeClass& someObj; 
public: 
    SomeOtherClass() {someObj = SomeClass();} 
}; 

И я получаю ошибку на конструктор для SomeOtherClass говоря Constructor for 'SomeOtherClass' must explicitly initialize the reference member 'someObj'.

Итак, я думаю, мой вопрос довольно прост. Как вы инициализируете ссылку?

+0

Под капотом ссылка не все, что отличается от указателя ... она просто должна быть инициализирована (нет «нулей») и не может быть изменена после ее инициализации. Если вы намерены безопасно держаться за объект, который вы выделяете, - и типичная переменная-член по значению не будет достаточной - посмотрите на использование [умных указателей] (http://en.wikipedia.org/wiki/Smart_pointer), например 'shared_ptr someObj;' или 'unique_ptr someObj;' ... и инициализация с помощью 'someObj (new SomeClass())'. – HostileFork

ответ

9

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

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

+0

На самом деле, теперь, когда я думаю об этом, мне могут не понадобиться ссылки на то, что я сейчас пытаюсь сделать. Но я все равно хотел бы знать, как это сделать. Так вы говорите, что два других ответа неверны? Должен ли я использовать 'someObj (* new SomeClass())' вместо этого? – anthropomorphic

+0

Думаю, да. Потому что два других ответа дали мне ошибки, но использование '* new' заставило его работать. – anthropomorphic

+3

Использование '* new' приведет к утечке памяти, так как теперь вы не можете освободить выделенную память для этого объекта (если вы не вернете ссылку обратно указателю). Я бы рекомендовал либо make 'someObj' указатель, либо никакой указатель или ссылку вообще (это означает, что вы храните' SomeClass' непосредственно в 'SomeOtherClass'). – AardvarkSoup

7

В рамках constructor initialization list:

SomeOtherClass() : someObj(SomeClass()) {} 

Update: я действительно предупредил, что это то, что вы не должны использовать дословно, потому что это будет приводить ссылки на ближайшее время-to be-dead временного экземпляра объекта.

Идея выше, но вам нужно будет передать объект со сроком жизни не короче, чем у экземпляра SomeOtherClass, который вы создаете.

+2

и что происходит после временного 'SomeClass()' разрушается? У тебя свисающая ссылка. –

+0

@GregHewgill: Убийственное упущение. Спасибо, что указали это. – Jon

+0

Вы не можете инициализировать ссылки на non-const с rvalues. 'someObj (SomeClass())' даже не компилируется. – fredoverflow

3

Вы должны инициализировать его в списке инициализации конструктора, так как нет «по умолчанию» или «нулевой» инициализации для справки:

class SomeOtherClass { 
    SomeClass& someObj; 
public: 
    SomeOtherClass(SomeClass& sc) : someObj(sc) {} 
}; 

Редактировать, как было указано в другом ответе, вы должны позаботиться о том, чтобы ваша ссылка была инициализирована объекту, срок жизни которого тот же или длиннее объекта, содержащего ссылку. В приведенном выше примере предположим, что sc переживает пример SomeOtherClass.

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