关于成员初始化参数列表的总结

参考C++ Prime 第四版 14.5

成员初始化列表和构造函数赋值语句的区别

1.先看下面的例子

 

   class Account {
        public:
             Account(const String name, double balance = 0.0);


       private:
             double _balance;
             String _name;
};

 

  对于构造函数的实现有两种方式:

方式1:

Account::Account(const String name, double balance) {
     _name = name;
     _balance = balance;
}

 

方式2:

Account::Account(const String name, double balance):_name(name) {

     _balance = balance;

}

 

在两种方式最终实现的效果是一样,但是其执行过程是有很大差别的,该差别主要是给据成员变量的类型区分。

 

成员类的执行过程

 

1.构造函数的执行有两个过程:

      过程1:隐式或显示初始化,该初始化也包含两个部分:

                1.给据继承关系,调用基类的构造函数,该步很好的理解

                2.执行所有成员类对象的默认构造函数,该步很容易被遗忘

                其中隐式还是显式的初始化,就取决于是否存在成员初始化列表,如果用初始化列表则是县式调用构造函数,否则是

                隐式的。

      过程2:一般的计算阶段,即执行函数体中的语句,该过程是一个赋值过程

2.由此看来方式1的构造函数实现:

  首先:隐式的调用了_name的默认构造函数,如果String中没有默认构造函数编译不会通过。

   然后:执行函数体的赋值语句,调用了String类的拷贝赋值函数

  方式2的构造函数实现:显示的调用了相应的构造函数

  方式2比方式1要高效,并且两种方式对成员类对象的构造也不同。

 

 

下面是代码实验,根据林锐博士高质量c++编程中的实现方式,编写String类的实现方式:

 

class String {
public:

 

 /*String();*/
 String(const char * str);
 String(const String& other);
 ~String();
 String& operator= (const String& other);
private:
 char *m_data;
};

String::String(const char *str) {
 cout<<"char* constructor"<<endl;
 if (NULL == str) {
  m_data = new char[1];
  m_data[0] = '/0';
 }
 else {
  int len = strlen(str);
  m_data = new char[len + 1];
  strcpy(m_data, str);
 }
}

 

String::~String() {
 delete[] m_data;
}

 

String::String(const String& other) {
 int len = strlen(other.m_data);
 m_data = new char[len + 1];
 strcpy(m_data, other.m_data);
}

 

String& String::operator =(const String &other) {
 cout<<"assignment constructor"<<endl;

 if (this == &other)
  return *this;

 delete[] m_data;

 int len = strlen(other.m_data);
 m_data = new char[len + 1];
 strcpy(m_data, other.m_data);

 return *this;
}

 

/*String::String() {
 cout<<"default constructor"<<endl;
 m_data = new char[1];
 m_data = '/0';
}*/

 

按照方式2执行下列语句

int _tmain(int argc, _TCHAR* argv[])
{
 Account *account = new Account("steven");
 return 0;
}

 

执行结果:屏幕打印 "char* constructor"

 

按照方式1执行该语句

编译报错:error C2512: “String”: 没有合适的默认构造函数可用,由此说明调用了默认构造函数。

 

我们把上面的注释去掉,继续执行

执行结果,屏幕打印:

char* constructor

default constructor

assignment constructor

 

对于内置类型的初始化

1.对于const数据成员和引用数据成员只能在构造函数处是化

2.其他类型应该等价

 

关于成员初始化成员列表的执行顺序:

成员处是换的执行顺序是根据根据成员的声明顺序执行的,并不根据成员列表的书写顺序,从该点来看,如果成员变量的初始化有顺序的换,还是把赋值放在函数体内比较清晰。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值