如果没有明确的禁止,C++默认是开启了隐式构造:
#include <iostream>
using namespace std;
class A{
public:
A(int a = 0)
{
cout<<"Construct A, this addr:"<<this<<endl;
}
A(const A& a)
{
cout<<"Copy Construct A, origin a addr:"<<&a<<", this addr:"<<this<<endl;
}
};
void func(A a)
{
cout<<"func a addr:"<<&a<<endl;
}
int main(){
A a1(1); //显示构造
cout<<"a1 addr:"<<&a1<<endl;
A a2 = 2; //隐式构造
cout<<"a2 addr:"<<&a2<<endl;
func(A(3)); //显示构造
func(4); //隐式构造
return 0;
}
运行程序输出:
Construct A, this addr:0x63fe1a //通过默认构造函数,显示构造a1
a1 addr:0x63fe1a
Construct A, this addr:0x63fe1b //通过隐式构造函数,先构造一个临时对象,记作tmpA1
Copy Construct A, origin a addr:0x63fe1b, this addr:0x63fe19 //拷贝构造函数再通过临时对象tmpA1构造对象a2
a2 addr:0x63fe19
Construct A, this addr:0x63fe1d //通过默认构造函数,显示构造匿名对象,记作tmpA3
Copy Construct A, origin a addr:0x63fe1d, this addr:0x63fe1c //拷贝构造函数通过匿名对象tmpA3构造函数参数a
func a addr:0x63fe1c
Construct A, this addr:0x63fe1f //通过默认构造函数,隐式构造一个临时对象记作tmpA4
Copy Construct A, origin a addr:0x63fe1f, this addr:0x63fe1e //拷贝构造函数通过临时对象tmpA4构造函数参数a
func a addr:0x63fe1e
通过将构造函数声明explicit,可以禁止隐式构造:
#include <iostream>
using namespace std;
class A{
public:
explicit A(int a = 0)
{
cout<<"Construct A, this addr:"<<this<<endl;
}
A(const A& a)
{
cout<<"Copy Construct A, origin a addr:"<<&a<<", this addr:"<<this<<endl;
}
};
void func(A a)
{
cout<<"func a addr:"<<&a<<endl;
}
int main(){
A a1(1); //显示构造,可以通过编译
A a2 = 2; //隐式构造,不能通过编译,error: conversion from 'int' to non-scalar type 'A' requested
func(A(3)); //显示构造,可以通过编译
func(4); //隐式构造,不能通过编译,error: could not convert '4' from 'int' to 'A'
return 0;
}