c++取经(其六)——类与对象初始化列表,类的隐式转换,explict,static修饰成员

本文详细讲解了C++中的初始化列表、类的隐式转换、explicit关键字的使用以及static修饰的成员(变量和函数)特性,帮助读者加深对类与对象概念的理解。
摘要由CSDN通过智能技术生成

目录

初始化列表:

类的隐式转换:

explicit:

static修饰成员:

我们来看static五个特性:

1. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明

2. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区

3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问

4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员


今天我们来讲一些很散的东西,通过这些很散的东西我们可以使我们之前学的东西更加通透,基本上把这些知识搞定,类与对象的知识基本上就差不多掌握了。

初始化列表:

定义:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。

这里我们不得再谈谈我们的构造函数了,我们通过一段代码来理解。


 class A {
 public :
	 A(int a=-1,int b=-20);

	
 private:
	 int _a;
	 int _b;
 };


 A::A(int a, int b) :_a(10), _b(20)// 初始化列表的写法,其实就是写再构造函数上的
 {

 }

 int main()
 {
	 A a1(20,15);
	 return 0;
 }

图解:

为证明这个说法,我们可以这样做:我们知道const修饰的数据只能在定义时赋值,不能在其他地方改变值,所以我们搞一个const修饰的数据。

放在初始化列表:

放在函数体内:

这足以证明,初始化列表是进行的定义,而函数体内进行的是成员的赋值。

其实我们不管有没有在初始化列表里定义成员,但是我们的初始化列表都会去过一遍每个成员,所以才使得,自定义类型回去调用他的默认构造,内置类型会让编译器来处理。

所以在这个代码中:


 class A {
 public :
	 A(int a=-1,int b=-20);
 private:
	 int _a;
	 int _b;
	 const int _c;
 };


 class B {
 public:

	 B(int d=100);

 private:
	 A _q1;
	 A _q2;
	 int _d;
 };


 A::A(int a, int b) :_a(a), _b(b),_c(100)
 {

 }


 B::B(int d )
 {

 }

 int main()
 {
	 A a1(20,15);
	 B b1;
	 return 0;
 }

b1的初始化:


类的隐式转换:

注意我们的类也可以隐式转换。
我们举个简单的例子:

我们来简单的画一个图

这就非常的通透了。

小优化->有些编译器遇到连续构造和拷贝构造,会直接就构造了,意思是不会经历中间的过程。
举个例子:

 class A {
 public:
	 A(int a = -1);
	 A(const A& ad);
	 ~A();
 private:
	 int _a;
 };



 A::A(int a) :_a(a)
 {
	 cout << " A::A(int a) :_a(a)" << endl;
 }

 A::~A()
 {
	 cout << "A::~A()"<<endl;
	 _a = -1;
 }

A::A(const A& ad)
 {
	cout << "A::A(A& a)" << endl;
	_a= ad._a;
 }


 A Func()
 {
	 A a=1;
	 return a;
 }

 int main()
 {
	 A a2=Func();
	 return 0;
 }

图解:

这里是vs2022的优化


explicit:

定义:修饰构造函数,使得不允许隐式转换
这里我们用张图简单带过:

此时就不能转换了,直接编译报错:


static修饰成员:

定义:声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化。

我们来看static五个特性:

1. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明

比如我们要定义一个静态成员变量

声明:

定义:

2. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区

因此我们可以在构造和拷贝里面加上_cout++用来观察生成了多少个同样的类
我们看这个代码:

 class A {
 public:
		A(int a = -1);
		A(const A& ad);
		~A();
 private:
	 int _a;
	 static int _cout;
 };

 int A::_cout = 0;


 A::A(int a) :_a(a)
 {
	 _cout++;       //加一
 }

 A::~A()
 {
	 _a = -1;
 }

A::A(const A& ad)
 {

	_cout++;        //加一
	_a= ad._a;
 }

 int main()
 {
	 A a1 = 1;
	 A a2 = 2;
	 A a3 = 3;
	 return 0;
 }

图解:

3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问

注意:静态成员也是类的成员,受public、protected、private 访问限定符的限制
所以我们将private换成public就可以进行访问

 

4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员

这意味这只能访问静态成员。

访问非静态成员要报错。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值