代码之家  ›  专栏  ›  技术社区  ›  Shiladitya Bose

C++如何从具有一个参数的派生类构造函数调用具有两个参数的超类构造函数?

  •  2
  • Shiladitya Bose  · 技术社区  · 7 年前

    例如,这:

    class shape {
    private:
        int height;
        int width;
    public:
        shape(int h, int w) {
            height = h;
            width = w;
        }
        void display() {
            std::cout << height << "\t" << width << std::endl;
        }
    };
    
    class square : public shape {
    public:
        square(int d) {
            shape(d, d);
        }
    };
    

    我收到以下错误消息:

    no default constructor exists for class "shape"
    

    为什么会这样?我知道它需要一个基类的默认构造函数,我想知道为什么它需要这样,如果我更改 square 构造函数进入初始化列表, square(int d): shape(d, d){} 。程序编译成功。有什么区别?

    3 回复  |  直到 7 年前
        1
  •  4
  •   Klaus    7 年前

    只需像这样调用构造函数:

    class square : public shape {
    public:
        square(int d): shape(d, d)
        {
        }
    };
    

    调用构造函数很重要 之前 派生类的构造函数的主体。您还应该初始化成员变量 之前 构造函数主体。

    如果不这样做,将完成所有对象的默认初始化,然后作为第二步完成赋值。在您的示例中,您首先尝试使用父类的默认初始化,这是不可能的,因为您没有默认构造函数。

    有关此主题的更多信息,请访问: http://en.cppreference.com/w/cpp/language/initializer_list

        2
  •  1
  •   songyuanyao    7 年前

    有什么区别?

    对于第一个示例,基类子对象将首先进行默认初始化(然后导致错误)。 shape(d, d); 在构造函数的主体中,只是创建一个临时 shape ,它与当前对象无关。

    对于第二个,即。 square(int d): shape(d, d){} ,使用 member initializer list ,基类子对象由构造函数初始化 shape::shape(int h, int w)

    在构成构造函数函数体的复合语句开始执行之前,完成所有直接基、虚拟基和非静态数据成员的初始化。成员初始值设定项列表是可以指定这些对象的非默认初始化的位置。对于无法默认初始化的成员,例如引用和常量限定类型的成员,必须指定成员初始值设定项。

        3
  •  0
  •   Achal    7 年前

    什么时候 parameterized constructor 已定义 shape(int h, int w) { } no default constructor 则编译器不会调用 default constructor 这就是它显示错误的原因。

    因此,要么添加 默认构造函数 或者按照您的建议添加

    square(int d): shape(d, d){ 
     /* ... */
    }