您的位置:首页 > 编程语言 > C语言/C++

C++中的构造函数与创建对象的(简单)过程

2015-01-19 15:22 288 查看
•构造函数

–和类名相同
–没有返回值类型
–只在建立对象的时候被自动调用一次
–调用构造函数的主要目的是初始化对象

•一个对象的创建过程:
–分配内存空间
–初始化成员变量,如果成员是对象,构造他
–调用构造函数

•默认的空参构造函数

构造函数的使用

•构造函数重载
–构造函数也是函数,拥有重载的特征
–重载的构造函数在构造对象时根据参数自动选择

•利用参数默认值简化构造函数
–构造函数也拥有函数参数默认值的特性
–使用默认值可以减少构造函数的个数

•构造函数的初始化列表
–初始化列表可以让构造函数在调用之前进行初始化工作
–如果类的成员变量是const或引用类型,使用初始化列表是不二选择

•实践中,类的声明和定义是分开的
–请试着将写的类分成头文件和实现两部分

<pre name="code" class="cpp">//构造方法
#pragma  在做游戏的公司里面初始化的方法有两种风格  一种是init这是本来做苹果转过来的  另外一种是在构造方法里面初始化 (这本来就是做C++的)

#include <iostream>
using namespace std;

//类
class Time{
//默认是私有的
int hour;
int min;
int sec;

//
void dida(){
sec++;
if (60 == sec) {
sec = 0;
min++;
}

if (60 == min) {
min = 0;
hour++;
}

if (24 == hour) {
hour = 0;
}
}

public:
#pragma  构造方法: 没有返回值 ,方法名与类名相同。构造方法在创建对象的时候一定会被动的调用一次。如果我们自己没有写构造方法,编译器会帮我们写一个无参的构造方法
//构造函数的参数可以给定默认值
/*
Time (int h = 0,int m = 0,int s = 0){
cout << "Time (int h,int m,int s)在构造方法中初始化成员变量" << endl;
//通常在构造方法里面去初始化成员变量
hour = h;
min = m;
sec = s;
}
*/

#pragma 初始化列表给成员变量初始化
//构造函数 可以用初始化列表 进行初始化
//只需要在参数括号后面加单冒号后面的就是初始化列表
Time (int h = 0,int m = 0,int s = 0):hour(h),min(m),sec(s){
cout << "初始化列表给成员变量初始化" << endl;

}

//重载 构造函数
/*

Time() {
hour = 0;
min = 0;
sec = 0;
cout << "创建对象的时候如果没有参数就默认找到这个无参的Time ()构造方法" << endl;
}
//如果把这个打开注释 main函数里面Time t2;会出现报错时因为上面的构造函数给定默认值了也可以不传参 所以不知道用哪一个
*/

//公开的初始化方法
void init(int h,int m,int s){
hour = h;
min = m;
sec = s;
}

//运行
void run(){
while (1) {

show();
dida();
//代表一个时间
time_t cur = time(0);//0是获取当前系统的时间
//注意理解
while (cur == time(0)) {
//死循环1秒钟
}
}
}

//显示
void show(){
cout << hour << "时" << min << "分" << sec << "秒" << endl;
}

};

//主函数
int main(int argc, const char * argv[])
{

//创建对象  并把参数传进去给构造函数
Time t(15,38,27);
t.show();
//t.run();//这个函数是死循环   下面的代码不会执行

#pragma 现在我希望这样也不报错,那该怎么办?
Time t2;// 一.方法重载  二.有参的构造方法给定参数的默认值
t2.run();

#pragma 在创建对象的时候  有参数的话就找到有参的构造函数。无参数的话就默认找到原来的无参的构造函数。
return 0;
}




运行结果如下:

初始化列表给成员变量初始化
15时38分27秒
初始化列表给成员变量初始化
0时0分0秒
0时0分1秒
0时0分2秒
0时0分3秒

Program ended with exit code: 9


利用构造函数初始化成员变量的两种方法:

一.直接在构造函数体中初始化

二.用初始化列表

既然两种方法都可以初始化成员变量,那它们之间到底有什么区别呢??

大多数情况下两种都可以,但是极个别情况必须要用初始化列表。它们的区别在于创建对象那个过程调用的时机。

在方法体里面直接赋值初始化的,是当构造函数已经开始调用了的时候。

而实用初始化列表的,是在构造函数调用前初始化

创建对象的过程

1.开辟内存空间

2.初始化成员变量

3.调用构造方法

也就是说构造方法是最后一个才调用的

这第2步首先得到的是垃圾值,接着再在构造函数体内赋值初始化成员变量。

然而利用初始化列表初始化成员变量的那种方法,它的意思是在第2步的时候告诉编译器:你就别给我垃圾值了,我直接利用初始化列表的值,然后再调用构造方法。

什么情况只能用初始化列表??

class Example{
int x=23451234;//创建对象的时候  这里调用第2步初始化得到的是垃圾值
public:
Example(){
x = 100;//初始化
}
};

/******例如这种情况就必须要使用初始化列表了********/
/*
class Example1{
int x=23451234;//创建对象的时候  这里调用第2步初始化得到的是垃圾值
int& r;//这是引用类型在创建的时候必须给它赋值  如果是这样可能得到垃圾值
public:
Example1(int a){
x = 100;//初始化
r = a;
}
};
*/
class Example1{
int x=23451234;//创建对象的时候  这里调用第2步初始化得到的是垃圾值
int& r;//这是引用类型在创建的时候必须给它赋值
public:
Example1(int a):r(a){ //利用初始化列表给引用初始化
x = 100;//初始化
#pragma 也就是说如果你的成员变量里面有引用类型的,那么必须使用初始化列表,否则等到构造方法一调用那么一切都晚了
}
};

class Example2{
int x=23451234;//创建对象的时候  这里调用第2步初始化得到的是垃圾值
int& r;//这是引用类型在创建的时候必须给它赋值
const int i;

public:
Example2(int a):r(a),i(200){ //利用初始化列表给引用初始化
x = 100;//初始化
//r = a;
// i = 300; //const一旦声明就不能改变它的值了
#pragma 也就是说如果你的成员变量里面有引用类型的,那么必须使用初始化列表,否则等到构造方法一调用那么一切都晚了
//如果成员变量是常量 也需要初始化列表初始化
}
};


总结:

成员变量里面有引用类型的变量 或者 是const常量类型的变量 那就必须要使用初始化列表来初始化成员变量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: