本文共 1426 字,大约阅读时间需要 4 分钟。
首先,对于创建一个对象:
1.开辟出一块空间
2.往里面填充一些垃圾值
3.使用构造函数对对象进行初始化
这里根据写法不同编译器会选择调用普通构造函数,或者拷贝构造函数或者赋值函数进行初始化,但是使用每种方式都要避免踩到相应的坑,比如使用普通构造函数就会遇到的问题。
首先,对于使用普通构造函数进行初始化对象,一般有两种方式:
1.
A a = A();//调用默认构造函数
A a = A(xx);//调用带参的构造函数
A a(xx);//调用带参的构造函数的简写形式
A a;//调用默认构造函数的简写形式
2.
使用初始化列表的方式调用构造函数
但是如果出现下面的的情况:
class Complex{
public:
Complex(double r, double i=0)
:m_real(r), m_imag(i){
cout<<"constructor function:"<<endl;
cout<<"m_real = "<<m_real<<" m_imag = "<<m_imag<<endl;
}
Complex(){
cout<<"No-argument constructor function:"<<endl;
}
friend void print(Complex c);
private:
double m_real;
double m_imag;
};
void print(Complex c){
cout<<"m_real = "<<c.m_real<<" m_imag = "<<c.m_imag<<endl;
}
int main(int argc, char *argv[])
{
Complex c1 = 5;
Complex c2;
c2 = 4;
print(10);
return 0;
}
这个时候就出现了complex c1=5的这种写法,这种写法就等于发生了一次隐式转换,即由int型隐式转换成了一个对象类型,那么是怎么发生这种转换的呢,是由于构造函数中存在单个参数造成的:
Complex(double r, double i=0)
:m_real(r), m_imag(i){
cout<<"constructor function:"<<endl;
cout<<"m_real = "<<m_real<<" m_imag = "<<m_imag<<endl;
}
此时编译器默认将Int类型当成5传进去构造出了一个对象。
这种写法有时候会造成一些错误:
#include <iostream>
using namespace std;
class MyString{
public:
MyString(int size){} //构造函数
MyString(const char* s=NULL){}//构造函数2
};
int main(){
MyString s1 = 'a';//这里原意是想用字符串"a"初始化s1,
//结果不小心将双引号""打成单引号''
在这种情况下,本来想创建一个对象s1,并给其初始化为a,即此时想要调用构造函数2,但是因为失误,而正好,有构造函数1满足条件被调用,就创建了97个空字符串对象,这显然是不对的。
所以对于单参的构造函数,容易发生隐式转化,避免的方法加上explicit关键字。
这种写法容易违背本身创建对象的目的,应该尽量避免。
转载地址:http://pwbab.baihongyu.com/