Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / C++拾遗--构造函数

前言对一个类而言,构造函数恐怕是最重要的一个成员函数了。关于构造函数的细节繁多,并且随着新标准的提出,构造函数有了新的特性。本文来集中探讨下构造函数的那些鲜为人知的一面。构造函数构造函数的作用众所周知:在类的对象被创建时,控制对象的初始化和赋值。构造函数的一般形式:类名(arg_list);其中arg_list是用逗号隔开的参数列表。特点:无返回值类型,且不可加const限制。默认构造函数需要特别指出,无参的构造函数是默认的,有参但都有默认参数的构造函数也是默认构造。------------------------------分割线------------------------------C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码 http://www.linuxidc.com/Linux/2014-05/101227.htm读C++ Primer 之构造函数陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm读C++ Primer 之智能指针 http://www.linuxidc.com/Linux/2011-08/40177.htm读C++ Primer 之句柄类 http://www.linuxidc.com/Linux/2011-08/40175.htm将C语言梳理一下,分布在以下10个章节中:
  1. Linux-C成长之路(一):Linux下C编程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成长之路(二):基本数据类型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成长之路(三):基本IO函数操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成长之路(四):运算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成长之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成长之路(六):函数要义 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成长之路(七):数组与指针 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成长之路(八):存储类,动态内存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成长之路(九):复合数据类型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成长之路(十):其他高级议题
举例证明:#include <iostream>
using namespace std;class MyClass
{
protected:
 int a = 0;
 int b{1};
public:
 MyClass(int a = 0, int b = 0):a(a), b(b)  //有默认实参的构造方法就是默认构造
 {
  cout << "MyClass(int a = 0, int b = 0)" << endl;
 } int getA()const
 {
  return a;
 }
 int getB()const
 {
  return b;
 }
};
int main()
{
 MyClass my;  //调用默认构造
 cout << "a = " << my.getA() << ends << "b = " << my.getB() << endl;
 cin.get();
 return 0;
}运行从运行结果,即可验证结论。有参但都有默认参数的构造函数也是默认构造,这一点恐怕是很多人都容易忽略的、默认构造初始化类的数据成员的规则:如果存在类内的初始值,用它来初始化成员。否则,默认初始化。(这个规则虽是标准,但大多数编译器还做不到)几个概念1.类内初始值。在上例代码中,int a = 0; int b{1};这种形式就是类内初始值。后面会说明何时使用类内初始值。2.默认初始化。内置类型,如int,double类型等。int->0,double->0.0。就是默认初始化。类类型,使用该类的默认构造初始化,就是默认初始化。默认构造并不是总是存在的,若有另一个构造函数(非默认构造)存在,则编译器并不会提供一个无参的默认构造。新标准提出了一种方式:如 MyClass() = default; 关键字 default 的这种使用,表明要求编译器生成一个默认的构造函数。3.初始值列表构造函数 MyClass(int a = 0, int b = 0):a(a), b(b){...}  其中 a(a), b(b)就是初始值列表。4.什么是初始化?什么是赋值?对象在内存中创建(有了内存实体),第一次有的值,叫做初始化。把原先的值覆盖掉,叫做赋值。一般情况下,构造函数在初始值列表中完成初始化,在函数体中完成赋值。这个结论并不好证明,但还是有办法的,办法就是借助:const类型和引用类型。如下代码:#include <iostream>
using namespace std;class MyClass
{
protected:
 int a = 0;
 const int ca = 0;
 int& ra;
public:
 MyClass(int a) :a(a), ca(a), ra(this->a){}
 int getA()const
 {
  return a;
 }
 void printCa()const
 {
  cout << "ca = " << ca << endl;
 }
 void printRa()const
 {
  cout << "ra = " << ra << endl;
 }
};
int main()
{
 MyClass my(1);
 cout << my.getA() << endl;
 my.printCa();
 my.printRa();
 cin.get();
 return 0;
}运行const类型和引用类型,在创建时,必须进行初始化。若是把 ca = a; ra = this->a; 移到构造函数体内部,则无法通过编译。也就是说,一旦进入构造函数体,初始化就已经完成了。需要指出,初始值列表的顺序并不代表着实际初始变量的顺序,而成员的声明顺序才是。更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2015-02/113672p2.htm