目录
一、前言
二、正文
1.隐式类型转换
1.1隐式类型转换的使用
2.static成员
2.1 static 成员的使用
2.1.1static修辞成员变量
2.1.2 static修辞成员函数
三、结语
一、前言
大家好,我们又见面了。昨天我们已经分享了初始化列表:https://blog.csdn.net/yiqingaa/article/details/144020182
今天让我们分享C++新知识——类型转换、static成员吧
二、正文
1.隐式类型转换
- ++支持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数。
- 构造函数前面加explicit就不再支持隐式类型转换。
- 类类型的对象之间也可以隐式转换, 需要相应的构造函数支持。
1.1隐式类型转换的使用
#include<iostream> using namespace std; class A { public: A(int a1) { _a1 = a1; } void Print() { cout << _a1 << " " << _a2 << endl; } private: int _a1; int _a2; }; int main() { A a1 = 1;//这里我们就用了隐式类型转换定义a1 //平常我们定义是这样:A a1(1); return 0; }
上面我们定义a1的时候,我们使用了隐式类型转换来定义,整形1其实先构造了一个A的临时对象,然后再用这个临时对象拷贝构造给a1。
在这个过程中,编译器会遇到连续构造+拷贝构造->优化为直接构造。
上面这个代码段是针对A(int a1)构造函数只有一个参数的情况下,如果有两个参数,我们想使用隐式类型转换,该如何操作呢?
如果我们按照错误示范1和2来操作的话,系统会报错。那么我们如何正确的操作呢?
这样写系统就不会报错啦
2.static成员
- 用static修饰的成员变量,称之为静态成员变量,静态成员变量一定要在类外进行初始化。
- 静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区。
- 用static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针。
- 静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。非静态的成员函数,可以访问任意的静态成员变量和静态成员函数。
- 突破类域就可以访问静态成员,可以通过类名:静态成员 或者 对象.静态成员 来访问静态成员变量和静态成员函数。
- 静态成员也是类的成员,受public、protected、private访问限定符的限制。
- 静态成员变量不能在声明位置给缺省值初始化,因为缺省值是为了给构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表。
2.1 static 成员的使用
2.1.1static修辞成员变量
#include<iostream> using namespace std; class Rabit { public: Rabit(string color, string gender) { _color = color; _gender = gender; ++_count; } Rabit(const Rabit& a) { _color = a._color; _gender = a._gender; ++_count; } private: //下面三个成员都是声明 //兔子的颜色和性别需要使用字符串,因此这里是string类型 static int _count;//兔子的总数 string _color;//兔子的颜色 string _gender;//兔子的性别 }; int Rabit::_count = 0;//给兔子总数初始化,静态成员必须在类外进行定义和初实话,上面只是声明有这个成员,并没有定义 int main() { Rabit a1("白色", "雄"); Rabit a2("灰色","雌"); return 0; }
上面是我们定义了一个类Rabit。其中_gender 和 _color都是独属于实例化成员的成员变量。
比如你可以说:
兔子a1的颜色是白色,性别是雄性。兔子a2的颜色是灰色性别是雌性。
但是你不能说兔子a1的兔子总数_count是多少吧?
兔子总数_count是静态成员,它是独属于类Rabit的,不属于任何一个实例化对象。虽然它们能调用静态成员_count,却不能修改它,例如:
假设我们将private注释掉,这样我们就能在类外面使用我们的成员变量。由上面的图可以看到,我们的a1虽然想要修改_count但是却没有什么用,因为_static是属于整个类Rabit的,而不是独属于某一个实例化对象的。而且通过调试我们可以看出,实例化对象a1中招不到_count。更说明了静态成员_static是属于整个类Rabit的,而不是独属于某一个实例化对象的。
- 同时静态成员_count并非只能通过实例化对象调用,通过使用 类名+:: 同样可以调用。
- 但是同样的,无法在类外面修改我们的静态成员_cout。静态成员_count只能在类里面修改,类外面是无法修改的。但是静态成员的初始化定义必须在类外面完成。
静态成员也是受类的成员,受public、protected、private访问限定符的限制。
- 静态成员变量还是受访问限定符的限制的,就像上面,我们的_count被限定符private修辞了,在下面我们通过 类名+::的方式去访问类Rabit会发现找不到我们的成员变量(_count、_color、_gender)。
- 同时静态成员既然受访问限定符的限制,那么肯定也会受到类域的限制(毕竟静态成员_count也是类的成员)
不使用 类名+::或者 实例化成对象. 的办法根本访问不到静态成员变量_count。
_count的生命周期虽然是全局的,但是会受到类域和访问限定符的限制。
- 同时,静态成员变量不能在声明位置给缺省值初始化,因为缺省值是为了给构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表。
如上图所示。初始化列表中不应该存在静态成员变量,既然静态成员变量不能存在初始化列表中,那么声明给初始值也肯定是错误的。会报以下错误:
2.1.2 static修辞成员函数
#include<iostream> using namespace std; class Rabit { public: Rabit(string color, string gender) { _color = color; _gender = gender; ++_count; } Rabit(const Rabit& a) { _color = a._color; _gender = a._gender; ++_count; } //获得兔子总数 static int GetCount()//静态成员函数 { _color = "无色";//这里是错误的用法 return _count; } //private: //下面三个成员都是声明 //兔子的颜色和性别需要使用字符串,因此这里是string类型 static int _count;//兔子的总数 string _color;//兔子的颜色 string _gender;//兔子的性别 }; int Rabit::_count = 0;//给兔子总数初始化,静态成员必须在类外进行定义和初实话,上面只是声明有这个成员,并没有定义 int main() { Rabit a1("白色", "雄"); Rabit a2("灰色","雌"); Rabit::_count=1000; //a1._count = 1000; return 0; }
如上图中,我们在静态成员函数GetCount中出现了成员变量color是错误的行为,因为GetCount是静态成员函数,而color是非静态成员变量(C++规定:静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。非静态的成员函数,可以访问任意的静态成员变量和静态成员函数)
所以,这也是为什么GetCount访问_count没问题,而访问_color就会出错的原因。
三、结语
集帅集美们,今天的分享就到此结束了,咱们下次再见~