1、对象的初始化
可以注意一下这些初始化的方式方法。
class Time{
private:
int Hour, Minute, Second;
public:
Time(int Hour, int Minute, int Second){
this->Hour = Hour;
this->Minute = Minute;
this->Second = Second;
}
}
//这些写法都调用了 构造函数
Time myTime1 = Time(12, 13, 52);
Time myTime2 =(12, 13, 52);
Time myTime3 = Time{12, 13, 52};
Time myTime4{12, 13, 52};
Time myTime5 = {12, 13, 52};、
//以下的都不调用 构造函数,调用的是拷贝构造函数
Time myTime6 = myTime1;
Time myTime7(myTime1);
Time myTime8{myTime1};
Time myTime9 = {myTime1};
2、类的隐式转换
class Time {
public:
int Hour, Minute, Second;
Time(int Hour) {
this->Hour = Hour;
this->Minute = 2;
this->Second = 30;
}
};
void main() {
Time mytime1 = 14;
Time mytime2 = {15};
Time mytime3 = (12, 13, 14, 15, 16);
cout << mytime1.Hour;
}
①第12句的地方,mytime1 和 mytime2 都调用了拷贝构造函数,其中发生了 隐式转换 ,因为本来 14 是个 int 类型,但编译器自动将 14 调用 Time 的构造函数,将其转换成了 Time 类型。
②第13句的地方,才是一个正常的更加明确清晰的写法。
③第14句的地方,看似有很多参数,最后实际上只是把 最后一个值 传入了 单参数构造函数中。
3、explicit
因为这种转换比较不好看,所以可以强制构造函数不做隐式转换,那么就在构造函数的声明中带有 explicit
。
class Time {
public:
int Hour, Minute, Second;
explicit Time(int Hour) { //相比之前,这个构造函数多了一个explicit
this->Hour = Hour;
this->Minute = 2;
this->Second = 30;
}
};
相比上面的两种写法,第4句这里添加了 关键字explicit
那么上面的 隐式转换 的构造方法都会失效。为了避免模糊,一般的但构造函声明为 explicit
。
4、成员函数末尾的const
在成员函数的末尾增加一个 const ,可以告诉系统,这个成员函数不会修改该对象里面的任何成员变量的值。即,这个函数不会修改 类对象 的任何状态。如:
class Time {
public:
int Hour, Minute, Second;
void Noone()const{
Hour += 10; //错误,const成员函数不可改值
}
};
可以注意一下第4句新定义的函数:用以限制成员函数的const。
5、mutable
在类中添加 mutable 的成员变量:
class Time{
public:
mutable int MyHour;
void Noone()const{
MyHour += 3; //现在即使有const修饰成员函数,也可以修改它的值了
}
}
现在,添加了 mutable
的成员变量,会一直处于可变状态,而且可以突破函数的 const 修饰。
6、cosnt成员变量的初始化
class Time{
const int A;
int m_Hour, m_Minute, m_Second;
Time(int Hour, int Minute, int Second):m_Hour(Hour),m_Minute(Minute),A(18){}
}
对于 const 成员变量,不能在构造函数内部赋值,只能在初始化列表里面初始化。
7、=default
对于无参构造函数,想要添加一个空的函数体的话:
class Time{
Time() = default;
}
第2句话相当于 Time(){}。就是创造了一个空的函数体而已。
8、=delete
这个写法是为了显式的禁用某个函数而引入的。