2009-09-14 5 views
55

Imagine У меня есть класс C++ Foo и класс Bar, который должен быть создан с помощью конструктора, в котором передается указатель Foo, и этот указатель должен оставаться неизменным в жизненном цикле экземпляра Bar. Каков правильный способ сделать это?Как инициализировать поле const в конструкторе?

На самом деле, я думал, что я мог бы написать, как приведенный ниже код, но он не компилируется ..

class Foo; 

class Bar { 
public: 
    Foo * const foo; 
    Bar(Foo* foo) { 
     this->foo = foo; 
    } 
}; 

class Foo { 
public: 
    int a; 
}; 

Любое предложение можно только приветствовать.

ответ

64

Вы должны сделать это в списке инициализатора:

Bar(Foo* _foo) : foo(_foo) { 
} 

(Обратите внимание, что я переименовал поступающую переменную, чтобы избежать путаницы.)

+3

+1, хотя я недавно узнал здесь, что переменные начиная с underscore теперь * официально * зарезервировано ;-) –

+1

Только если за ними следует заглавная буква. – GManNickG

+1

или находятся в пространстве имен! Или за ним следует другое подчеркивание. Так что да, это технически законно в этом случае, но я бы сказал, что легче просто притвориться, что они защищены, а не использовать их вообще. :) – jalf

2

Используйте ссылку:

Foo& foo; 
Bar(Foo& f) : foo(f) { } 

You затем можно легко обратиться к foo в Bar:

foo.doSomething(); 
+1

Я голосую как «отрицательный», потому что, если это был единственный ответ, я мог ошибочно предположить, что использование ссылки было единственным способом ее достижения, в то время как вместо этого, как показывает другой ответ, трюк - это список инициализаторов. – puccio

+0

IMHO, ссылки в этом случае гораздо более элегантны, потому что указатель не должен меняться вообще после его инициализации :) – AraK

+1

Но вопрос в том, как инициализировать указатель. –

0

попробовать: Bar(Foo* xfoo) : foo(xfoo) {}

12

Инициализация константных член и другие специальные случаи (например, родитель классы) может быть выполнен в списке инициализатора

class Foo { 
private: 
    const int data; 
public: 
    Foo(int x) : data(x) {} 
}; 

Или, аналогично, для родительской инициализации

class Foo { 
private: 
    int data; 
public: 
    Foo(int x) : data(x) {} 
}; 

class Bar : Foo { 
public: 
    Bar(int x) : Foo(x) {} 
}; 
5

Вам нужно инициализировать foo в списке инициализаторов.

class Bar { 
    Foo* const foo; 
    public: 
    Bar(Foo* f) : foo(f) {...} 
}; 
16

Я считаю, что вы должны сделать это в инициализаторе. Например:

Bar(Foo* foo) : foo(foo) { 
} 

В качестве примечания, если вы никогда не изменит то, что Foo точки на, передать его в качестве справки:

Foo& foo; 

Bar(Foo& foo) : foo(foo) { 
} 
+2

+1: Используйте ссылки везде, где хотите, указатели, где вам нужно. –

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