【问题标题】:Using initializer lists with inherited variables使用带有继承变量的初始化列表
【发布时间】:2011-09-12 20:42:32
【问题描述】:

我一直在摆弄一个程序大约 20 分钟,我发现由于某种原因它不允许我在初始化列表中使用继承变量。这个程序,例如:

class A {
protected:
        int i;
};

class B : public A {
public:
        B() : i(45) { }
};

int main() {
        B b;
}

会报错

错误:“B”类没有任何名为“i”的字段

但是,如果你把构造函数改成这样:

B() { i = 45; }

它编译。

我从来不知道你不能初始化继承的变量。我的问题是,为什么?

【问题讨论】:

    标签: c++ inheritance initializer-list


    【解决方案1】:

    你不能在 C++ 中做到这一点。正常的方法是在父类中有一个 (protected) 构造函数,它接受一个用于设置变量的参数。

    几乎从不建议使用这样的受保护属性,因为它会让子类违反父类不变量,这只会在以后引起严重的调试问题。

    【讨论】:

      【解决方案2】:

      您必须在 A 类中定义带参数的公共构造函数。然后在 B 类中使用基类的构造函数。 示例:

      #include <iostream>
      using namespace std;
      
      class A {
      protected:
          int i;
      public:
          A(int number) : i(number) {}
      };
      
      class B : public A {
      public:
          B() : A(45) { }
      };
      
      int main() {
          B b;
      }
      

      【讨论】:

        【解决方案3】:

        一个对象只能被初始化一次:当它第一次存在时。

        A 在其构造函数中初始化其所有成员变量(在执行其构造函数的主体之前)。因此,B 无法初始化A 的成员变量,因为该成员变量已经被A 的构造函数初始化。

        (在这种特定情况下,技术上i 未初始化,因为A 没有初始化它;也就是说,初始化其成员变量仍然是A 的责任。)

        【讨论】:

        • 嗯,严格来说,全局变量可以被初始化两次。首先是零初始化,然后是初始化它的内容。不过,对于这种情况是正确的。 :)
        • 啊,这很有道理。谢谢。
        猜你喜欢
        • 2018-01-21
        • 1970-01-01
        • 1970-01-01
        • 2012-11-08
        • 2015-03-02
        • 1970-01-01
        • 1970-01-01
        • 2021-07-27
        • 1970-01-01
        相关资源
        最近更新 更多