为什么按值传递给函数和按值传递给另一个构造函数时,构造函数的调用会有所不同?

Why is there a difference in call of constructors when passed by value to a function and pass by value to another constructor?

我正在尝试以下程序:

#include <iostream>
using namespace std;
class Type{
    int i;
    public: 
    Type() {cout << "type constructor "<<endl;}
    Type (const Type &) { cout << "type copy constructor called" << endl;}
};

class MyClass {
    Type variable;
public:
    MyClass(Type a) {   
    cout << "inside MyClass constructor "<<endl;
    variable = a;
    }
};
void fun (Type){
    return;
}

int main (){
    Type t;
    cout <<"t created"<<endl;
    MyClass tmp = MyClass(t);
    cout<<"calling fun"<<endl;
    fun(t);
}

这个输出是:

type constructor 
t created
type copy constructor called
type constructor 
inside MyClass constructor 
calling fun
type copy constructor called

我想知道为什么当我将它传递给 MyClass 构造函数时调用默认构造函数,为什么当我将它传递给 fun() 时调用复制构造函数?
顺便说一句,当我使用初始化列表时也会发生同样的情况。

为两个参数(MyClass 构造函数和 fun 构造函数调用了复制构造函数,您发布的日志报告说。
事实上,您有两次以下行:

type copy constructor called

为数据成员 variable 调用默认构造函数,因为它没有显式初始化。
如果您使用这样的初始化列表,也会发生同样的情况:

MyClass(Type a): variable{} {
    //...
}

实际上,如果您没有任何初始化列表,variable 是默认初始化的,因此没有理由期待不同的日志。

I am wondering why default constructor is called when I pass it to MyClass constructor

此处与传参无关。 variable作为成员变量,首先会默认构造

class MyClass {
    Type variable;  
public:
    MyClass(Type a) {   // variable will be default constructed at first, since it's not initialized via member initializer list
    cout << "inside MyClass constructor "<<endl;
    variable = a;       // then variable is assgined via assignment operator
    }
};

您可以指定成员初始化器列表如何初始化 variable,例如

class MyClass {
    Type variable;  
public:
    MyClass(Type a) : variable(a) {   // variable will be direct initialized via copy constructor
    cout << "inside MyClass constructor "<<endl;
    // variable = a;                  // no need for assignment
    }
};

这种情况下不会调用默认构造函数。