正文
explicit关键字
构造函数不仅可以构造与初始化对象,对于单个参数
或者除第一个参数无默认值其余均有默认值
的构造函数,还具有类型转换
的作用。
🍁什么是类型转换?
int a=100; double b = a;
如上所示,a
并不是直接赋值给b
,而是先进行了隐式类型转换
:
- 创建一个
double
类型的临时变量
; - 将
a
的值赋予临时变量
; - 将
临时变量
的值赋予b
。
单参数构造函数
🍁举例
定义一个Date
类,且该类的构造函数只有一个参数,我们称为单参数构造函数
:
class Date { public: Date(int year) :_year(year) {} private: int _year=0; };
Date d1(2023); • 1
这是我们常见的创建一个对象的写法,此外还可以这样写:
Date d2 = 2023;
🍁注意事项
此处这种写法是我们的赋值运算符重载吗?
答案是,当然不是。赋值重载实现的功能是用一个已存在的对象赋值给另外一个对象。
那么为什么100可以赋值给d1呢?这是由于类型转换的原因。具体实现过程如下:
用100构造一个Date类型的临时对象;
再用临时对象对d1进行拷贝构造。
总结起来就是,该语句实现了2个过程——1个构造+1个拷贝构造
。
🍁如何证明这一过程呢?
这就要用到explicit
关键字了。
explicit
修饰的构造函数禁止类型转换
。
🍁示例
class Date { public: explicit Date(int year) :_year(year) {} private: int _year=0; int _month=0; int _day=0; }; int main() { Date d2 = 100; return 0; }
如图所示,此时编译器会报错。
多参数构造函数
多参数构造函数与单参数类似。C++98
中只支持除第一个参数外,其余参数都有默认值的情况。C++11
中引进了一种新的写法。
🍁示例1(C++98)
class Date { public: //除第一个参数外,其余都有默认值 //加上explicit关键字会报错 Date(int year, int month=0, int day=0) :_year(year), _month(month), _day(day) {} private: int _year; int _month; int _day; }; int main() { Date d2 = 100; return 0; }
🍁示例2(C++11)
class Date { public: Date(int year, int month,int day) :_year(year), _month(month), _day(day) {} private: int _year; int _month; int _day; }; int main() { Date d2 ={2023,10,26};//使用大括号 return 0; }
static成员
static成员的概念
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化。
class A { public: int getN() { return n; } private: //类中进行声明 static int n; }; //类外进行定义与初始化 int A::n = 0;
static成员的特性
- 静态成员变量必须在
类外定义
,定义时不添加static
关键字,类中只是声明
; - 类静态成员即可用
类名::静态成员
或者对象.静态成员
来访问; - 静态成员也是类的成员,受
public、protected、private
访问限定符的限制;
🍁示例1
class A { public: int getN() { return n; } public: //类中进行声明 static int m; private: //类中进行声明 static int n; }; //在类外进行定义与初始化 int A::n = 0; int A::m = 0; int main() { A a; a.m += 10; cout << a.getN() << endl; cout << a.m<< endl; return 0; }
- 4静态成员函数没有隐藏的
this
指针,不能访问任何非静态成员
;
🍁示例2
class B { public: static int getN() { //错误示例 //静态函数不能直接访问非静态成员 //_a++; return n;//可以访问静态成员 } private: static int n; int _a; };
- 静态成员为
所有类对象所共享
,不属于某个具体的对象,存放在静态区。
🍁一道有趣的试题
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
这道题可以很好的帮我们理解第5条性质。
🌼解题思路
利用static
成员被类的所有对象所共用的特性。声明static
成员变量n
,每创建一个对象就++n
。再声明一个static
成员变量sum
,求所有n
的和。
🌼题解
#include <regex> class sum { public: sum() { _sum+=_i; ++_i; } static int GetSum() { return _sum; } private: static int _sum; static int _i; }; int sum::_sum = 0; int sum::_i = 1; class Solution { public: int Sum_Solution(int n) { sum a[n]; return sum::GetSum(); } }; public: sum()