为什么要调用构造函数?

Why is constructor being invoked?

为什么要在这里调用 s1() 构造函数?

#include<iostream>

struct s1 {
    s1(int tmp) {

    }

    s1() {
        std::printf("s1 invoked");
    }
};

struct s2 {
    s1 s;
    s2(s1& s) {
        this->s = s;
    }
};
int main() {

    s1 o1(5);
    s2 o2(o1);
    return 0;
}

结果: s1 invoked

为什么在 s2(s1& s) 中通过引用传递调用 s1() 构造函数?

鉴于 s2(s1&) 的实施:

s2(s1& s) {
    this->s = s;
}

数据成员s首先通过默认构造函数进行默认初始化,然后在构造函数体内赋值。

你应该直接在member initializer list中初始化它。

s2(s1& s) : s(s) // direct-initialize data member s from parameter s
{}

从 main 传递 s1 不会默认构造一个。有一个成员 s1 没有出现在 s2 的构造函数的成员初始化程序中。

看来你想要

struct s2 {
    s1 s;
    s2(s1& s) : s(s) {
    }
};

假设您根本没有初始化 s 成员。当然,它不能只是不构造。所以它的默认构造函数被隐式调用。

只有所有成员(和基础类)都被初始化(构造)之后,s2构造函数的主体(和行this->s = s) 被执行。到那时, s 成员已经默认构造。正如其他答案所建议的那样,您可以通过在成员初始化器列表中显式调用构造函数来避免这种情况。