【问题标题】:How to initialize a const field in constructor?如何在构造函数中初始化 const 字段?
【发布时间】:2010-11-28 06:20:57
【问题描述】:

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

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

class Foo;

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

class Foo {
public:
  int a;
};

欢迎提出任何建议。

【问题讨论】:

    标签: c++ constructor constants ctor-initializer


    【解决方案1】:

    你需要在初始化列表中进行:

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

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

    【讨论】:

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

    我相信您必须在初始化程序中执行此操作。例如:

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

    附带说明,如果您永远不会更改 foo 指向的内容,请将其作为参考传递:

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

    【讨论】:

    • +1:在任何你想要的地方使用引用,在你需要的地方使用指针。
    【解决方案3】:

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

    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) {}
    };
    

    【讨论】:

      【解决方案4】:

      你需要在初始化列表中初始化 foo。

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

      【讨论】:

        【解决方案5】:

        使用参考:

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

        然后您可以在Bar 中轻松引用foo

        foo.doSomething();
        

        【讨论】:

        • 我投票为“否定”,因为如果这是唯一的答案,我可能会错误地认为使用引用是实现它的唯一方法,而正如其他答案所示,诀窍是初始化列表。
        • 恕我直言,在这种情况下引用更加优雅,因为指针在初始化后根本不能改变:)
        • @hacker 我刚刚说了我认为做同样事情的更好方法。
        • 我认为这个答案被低估了。如果你想引用一个对象,并且被引用对象的地址永远不能改变,那么引用要比 const 指针好得多。另一方面,也许您想指向一个 const 对象?那是另外一回事,语法略有不同。
        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-28
          • 1970-01-01
          • 2020-01-18
          • 2014-01-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多