C++日记——Day8:构造函数、explicit、初始化列表

构造函数:

1、在类中有一种特殊的成员函数,它的名字和类相同我们在创建类对象的时候,这个特殊的成员函数会被系统自动调用,所以我们可以简单的理解成:构造函数的目的据说初始化类对象的数据成员。

2、构造函数没有返回值。这也是构造函数的特殊之处。

3、不可以手工调用构造函数,否则编译就会出错。

4、正常情况下构造函数应该被声明为public,因为我们创建一个对象时系统要替我们调用构造函数,这说明构造函数是一个public才能被外界调用,因为类缺省的成员是私有成员,所以我们必须把构造函数声明为public函数,否则无法直接创建该类的对象。

Time myTime = Time(12, 13, 14);
Time myTime2(12, 13, 15);
Time myTime3 = Time{12, 13, 15};
Time myTime4{12, 13, 15};
Time myTime5 = {12, 13, 15};

 

多个构造函数:

多个构造函数可以为类对象的创建提供多种初始化方法。但是多个构造函数之间要有不同的形参。

 

对象拷贝时不会调用传统意义上的构造函数,他们调用的不是传统意义上的构造函数,他们调用的实际是拷贝构造函数。

//Time.h

#ifndef __MYTIME__
#define __MYTIME__

class Time {
public:
	int Hour;
	int Minute;
	int Second;

	void initTime(const int &tmp_hour, const int &tmp_minute, 
		const int &tmp_second, const int &tmp_millsecond);

private:
	int MillSecond;
	void initMillSecond(const int &tmp_millsecond);

public:
	Time(const int &tmp_hour, const int &tmp_minute,
		const int &tmp_second, const int &tmp_millsecond);

    Time();

};
#endif


//--------------------------------------------------------------------------

//Time.cpp
#include "Time.h"

void Time::initTime(const int &tmp_hour, const int &tmp_minute, 
	const int &tmp_second, const int &tmp_millsecond) {
	Hour = tmp_hour;
	Minute = tmp_minute;
	Second = tmp_second;
	initMillSecond(tmp_millsecond);
}

void Time::initMillSecond(const int &tmp_millsecond) {
	MillSecond = tmp_millsecond;
}

Time::Time(const int &tmp_hour, const int &tmp_minute,
	const int &tmp_second, const int &tmp_millsecond) {
	Hour = tmp_hour;
	Minute = tmp_minute;
	Second = tmp_second;
	initMillSecond(tmp_millsecond);
}

Time::Time(){
    Hour = 12;
	Minute = 14;
	Second = 16;
	initMillSecond(67);
}



//---------------------------------------------------------------------------
//file1.cpp

#include "Time.h"

//对象拷贝
Time myTime;

Time myTime2(myTime);
Time myTime3 = myTime;
Time myTime4 = { myTime };
Time myTime5 { myTime };

 

函数默认值

规定:

1、默认值只能放在函数声明中,除非该函数没有函数声明。

2、在具有多个参数的函数中指定默认值时,默认参数都必须出现在不默认参数的右边,一旦某个参数开始指定默认值,它右边的所有参数必须指定默认值

//Time.h

#ifndef __TIME_H_
#define __TIME_H_
class Time{
public:
    int Hour;
    int Minute;
    int Second;
    
public:
    Time(const int &tmp_hour, const int &tmp_minute = 32 , const int &tmp_second = 12);

};

#endif


//--------------------------------------------------------------------------
//Time.cpp

#include "Time.h"

Time::Time(const int &tmp_hour, const int &tmp_minute, const int &tmp_second)
{
    Hour = tmp_hour;
    Minute = tmp_minute;
    Second = tmp_second;
}

 

隐式转换和explicit

编译器,在私下干了很多我们不了解的事情。

//Time.h

#ifndef __TIME_H_
#define __TIME_H_
class Time{
public:
    int Hour;
    int Minute;
    int Second;
    
public:
    Time(const int &tmp_hour, const int &tmp_minute = 32 , const int &tmp_second = 12);

};

#endif


//--------------------------------------------------------------------------
//Time.cpp

#include "Time.h"

Time::Time(const int &tmp_hour)
{
    Hour = tmp_hour;
    Minute = 2;
    Second = 1;
}

//--------------------------------------------------------------------------
//file.cpp
#include "Time.h"

func(Time tmp_time){
    return;
}

Time myTime = 40; //正常情况下是不可以的,但是编译器对 40 做了隐式变换,将40 转换成了 Time(40)
                  //含糊不清的写法
Time myTime2 = (1, 2, 3, 4); //也编译通过了,执行了 Time(4) 的变换
func(24); //也发生了隐式转换


是否可以强制系统,明确要求构造函数不能做隐式类型转换?可以,如果构造函数声明中带有explicit,则这个构造函数只用与初始化和显示转换

explicit样例:(注意:要加在函数声明中)

//Time.h

#ifndef __MYTIME__
#define __MYTIME__

class Time {
public:
	int Hour;
	int Minute;
	int Second;

	void initTime(const int &tmp_hour, const int &tmp_minute, 
		const int &tmp_second, const int &tmp_millsecond);

private:
	int MillSecond;
	void initMillSecond(const int &tmp_millsecond);

public:
	explicit Time(const int &tmp_hour, const int &tmp_minute,
		const int &tmp_second, const int &tmp_millsecond);

    explicit Time(const int &tmp_hour);

};
#endif


//--------------------------------------------------------------------------

//Time.cpp
#include "Time.h"

void Time::initTime(const int &tmp_hour, const int &tmp_minute, 
	const int &tmp_second, const int &tmp_millsecond) {
	Hour = tmp_hour;
	Minute = tmp_minute;
	Second = tmp_second;
	initMillSecond(tmp_millsecond);
}

void Time::initMillSecond(const int &tmp_millsecond) {
	MillSecond = tmp_millsecond;
}

Time::Time(const int &tmp_hour, const int &tmp_minute,
	const int &tmp_second, const int &tmp_millsecond) {
	Hour = tmp_hour;
	Minute = tmp_minute;
	Second = tmp_second;
	initMillSecond(tmp_millsecond);
}

Time::Time(const int &tmp_hour){
    Hour = tmp_hour;
	Minute = 14;
	Second = 16;
	initMillSecond(67);
}


//---------------------------------------------------------------------------
//file1.cpp

#include "Time.h"

//对象拷贝
Time myTime;

Time myTime2(1, 2, 12, 34);           //可以
Time myTime3 = myTime{1, 2, 12, 34}; //可以
Time myTime4 = { 1, 2, 12, 34};      //不可以,说明这个在初始化时发生了隐式类型转换
Time myTime5 { 1, 2, 12, 34 };       //可以


Time myTime = 40;            //报错 
Time myTime2 = (1, 2, 3, 4); //报错 
func(24);                   //报错 

对于单参数的构造函数,一般都声明为explicit,除非有特殊原因。

 

构造函数初始化列表

专门用来初始化成员变量

//Time.h

#ifndef __MYTIME__
#define __MYTIME__

class Time {
public:
	int Hour;
	int Minute;
	int Second;


private:
	int MillSecond;

public:
	explicit Time(const int &tmp_hour, const int &tmp_minute,
		const int &tmp_second, const int &tmp_millsecond);

};
#endif


//--------------------------------------------------------------------------

//Time.cpp
#include "Time.h"

void Time::Time(const int &tmp_hour, const int &tmp_minute, 
	const int &tmp_second, const int &tmp_millsecond) 
        :Hour(tmp_hour), Minute(tmp_minute), Second(tmp_second), MillSecond(tmp_millsecond)
{
	cout << "初始化" << endl;
}

这里初始化列表的初始化顺序,取决于它们声明时的顺序而不是在初始话列表中的顺序。要避免在初始化列表中以用一个成员变量给另一个成员变量赋值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值