如何在构造函数中初始化const字段?

puc*_*cio 66 c++ constructor const ctor-initializer

想象一下,我有一个C++类Foo和一个类Bar,它必须用一个构造函数创建,其中传递一个Foo指针,这个指针意味着在Bar实例生命周期中保持不变.这样做的正确方法是什么?

事实上,我认为我可以像下面的代码一样编写,但它不能编译..

class Foo;

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

class Foo {
public:
  int a;
};
Run Code Online (Sandbox Code Playgroud)

任何建议都是受欢迎的.

Jim*_*uck 78

您需要在初始化列表中执行此操作:

Bar(Foo* _foo) : foo(_foo) {
}
Run Code Online (Sandbox Code Playgroud)

(请注意,我重命名了传入变量以避免混淆.)

  • 关于重命名,它是少数可以在具有不同含义的表达式中两次写入相同名称的地方之一:'Bar(Foo*foo):foo(foo){}'将在初始化列表中适当地工作第一个foo必须是基类或当前类的属性,但在括号内,参数隐藏属性,因此'foo'是那里的传入参数. (15认同)
  • +1,虽然我最近在这里了解到变量以下划线开头现在*正式*保留;-) (3认同)
  • jalf,但我喜欢他们.我宁愿违法. (3认同)
  • 仅当它们后跟大写字母时。 (2认同)
  • 或者在命名空间范围内!或者后跟另一个下划线。所以是的,在这种情况下从技术上讲这是合法的,但我认为假装它们被保留而不使用它们更容易。:) (2认同)

Sin*_*hot 19

我相信你必须在初始化器中做到这一点.例如:

Bar(Foo* foo) : foo(foo) {
}
Run Code Online (Sandbox Code Playgroud)

作为旁注,如果你永远不会改变foo指向的内容,请将其作为参考传递:

Foo& foo;

Bar(Foo& foo) : foo(foo) {
}
Run Code Online (Sandbox Code Playgroud)

  • +1:在任何地方使用引用,指向您需要的地方. (2认同)

ezp*_*zpz 14

初始化const成员和其他特殊情况(例如父类)可以在初始化列表中完成

class Foo {
private:
   const int data;
public:
   Foo(int x) : data(x) {}
};
Run Code Online (Sandbox Code Playgroud)

或者,类似地,对于父初始化

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

class Bar : Foo {
public:
   Bar(int x) : Foo(x) {}
};
Run Code Online (Sandbox Code Playgroud)


Kei*_*thB 6

您需要在初始化列表中初始化foo.

class Bar {
    Foo* const foo;
  public:
    Bar(Foo* f) : foo(f) {...}
};
Run Code Online (Sandbox Code Playgroud)