设为首页 加入收藏

TOP

C++拾遗--构造函数
2015-02-25 16:15:04 来源: 作者: 【 】 浏览:25
Tags:拾遗 构造 函数

前言


对一个类而言,构造函数恐怕是最重要的一个成员函数了。关于构造函数的细节繁多,并且随着新标准的提出,构造函数有了新的特性。本文来集中探讨下构造函数的那些鲜为人知的一面。


构造函数


构造函数的作用众所周知:在类的对象被创建时,控制对象的初始化和赋值。


构造函数的一般形式:


类名(arg_list);


其中arg_list是用逗号隔开的参数列表。


特点:无返回值类型,且不可加const限制。


默认构造函数


需要特别指出,无参的构造函数是默认的,有参但都有默认参数的构造函数也是默认构造。


------------------------------分割线------------------------------


C语言梳理一下,分布在以下10个章节中:


举例证明:


#include
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
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; 移到构造函数体内部,则无法通过编译。也就是说,一旦进入构造函数体,初始化就已经完成了。


需要指出,初始值列表的顺序并不代表着实际初始变量的顺序,而成员的声明顺序才是。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C++拾遗--函数模板 下一篇C++拾遗--lambda表达式

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: