🌈个人主页:羽晨同学
💫个人格言:“成为自己未来的主人~”
首先,我们先来看一段正常的构造和拷贝构造的代码:
#include<iostream>
using namespace std;
class A
{
public:
//单参数构造函数
//explicit A(int a)
A(int a)
:_a(a)
{
cout << "A(int a)" << endl;
}
A(const A& aa)
:_a(aa._a)
{
cout << "A(const A& aa)" << endl;
}
private:
int _a;
int _a1;
int _a2;
};
int main()
{
A aa1(1);
A aa2 = aa1;
//A aa1 = 3;
return 0;
}
在这段代码当中,我们用到了拷贝构造和构造。
大家再来看下面的一段代码:
#include<iostream>
using namespace std;
class A
{
public:
//单参数构造函数
//explicit A(int a)
A(int a)
:_a(a)
{
cout << "A(int a)" << endl;
}
A(const A& aa)
:_a(aa._a)
{
cout << "A(const A& aa)" << endl;
}
private:
int _a;
int _a1;
int _a2;
};
int main()
{
//A aa1(1);
//A aa2 = aa1;
A aa1 = 3;
return 0;
}
这段代码,将3直接给了aa1,但是代码并不会进行报错,这是为什么呢?
在这个其中,涉及到了一个很重要的知识点,叫做隐式类型转换。
什么意思呢?就是3构造了一个A类型的临时变量,然后a类型的临时变量进行拷贝构造,给了aa1
所以,在这个过程中涉及到了两步,第一步是默认构造,第二步是拷贝构造,但是这种连续构造编译器会进行优化,所以显示出来的结果为直接构造
明白了这个道理之后,我们再来看下面的这个代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class A
{
public:
//单参数构造函数
//explicit A(int a)
A(int a)
:_a(a)
{
cout << "A(int a)" << endl;
}
A(const A& aa)
:_a(aa._a)
{
cout << "A(const A& aa)" << endl;
}
private:
int _a;
int _a1;
int _a2;
};
int main()
{
//A aa1(1);
//A aa2 = aa1;
//A aa1 = 3;
A& raa = 3;
return 0;
}
这个代码会进行报错,这是为什么呢?
原因就是这个的raa是3类型转换之后产生的临时变量的别名,但是临时变量具有常性,不能进行修改。所以,为了保证权限不被放大,我们应该在前面加一个const来进行修饰。
const A& raa = 3;
上面我们讲的是单参数构造的情况,那么多参数构造的情况呢?
我们来看下面的这部分代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class A
{
public:
//单参数构造函数
//explicit A(int a)
//A(int a)
// :_a(a)
//{
// cout << "A(int a)" << endl;
//}
//A(const A& aa)
// :_a(aa._a)
//{
// cout << "A(const A& aa)" << endl;
//}
A(int a1, int a2)
:_a(0)
,_a1(a1)
,_a2(a2)
{
}
A(const A& aa)
:_a(aa._a)
{
cout << "A(const A& aa)" << endl;
}
private:
int _a;
int _a1;
int _a2;
};
int main()
{
//A aa1(1);
//A aa2 = aa1;
//A aa1 = 3;
//const A& raa = 3;
A aaa1(1, 2);
A aaa2 = aaa1;
const A& aaa3 = { 1,2 };
return 0;
}
上面的这个就是多参数构造部分的代码,我们可以看到的是,和单参数构造是差别不大的。
好了,本期的文章就到这里,我们下一期再见。