C++学习之旅第二站(类和对象进阶)

吾生也有涯,而知也无涯。这篇文章主要讲述C++学习之旅第二站:类和对象进阶相关的知识,希望能为你提供帮助。

一.this指针I.定义

      一个隐含于每一个成员函数中的特殊指针,它是一个指向操作该成员函数的对象
II.使用场景
      当一个对象调用成员函数时,编译程序先将对象的地址赋值给this指针,然后再调用成员函数存取数据成员时,由隐含作用this指针
III.产生起源
在C++产生初期,没有专门的C++编译器,处理方法就是将C++代码翻译成c的代码,然后通过C编译器进行编译
//C++程序
#include< iostream>
using namespace std;
class Studnet
public:
int age;
void Setage(int p);
;
void Studnet::Setage(int p)
age=p;

int main()
Student td;
td.Setage(34);
return 0;

//翻译为c程序后如下
#include< stdio.h>
struct Student
int age;
;
void Setage(struct Student *this,int p)
this-> age=p;

int main()
struct Student td;
Setage(& td,34);
return 0;

IV.作用
指向成员函数所作用的对象
具体使用:
场景一:
非静态成员函数可以直接通过this来代表指向该函数作用的对象的指针
#include< iostream>
using namespace std;
class Complex
public:
double imag,real;
public:
void Print()cout< < real< < ","< < imag;
Complex(double r,double i)imag=i,real=r
Complex Addone()
this-> real++;
this-> Print();

;
int main()
Complex c1(1,3),c2(7,8);
c2= c1.Addone();
return 0;

场景二:
#include< iostream>
using namespace std;
class Student
public:
int age;
public:
void Hello()cout < < "hello"< < endl;
//等价于void Hello(Student *this)cout< < "hello"< < endl;
;
int main()
Student *p=NULL; //空指针
p-> Hello(); //类似于Hello(p);
return 0;

注意:
静态成员函数中不能使用this指针,因为静态成员函数并不具体作用与某个对象
典型例题

问题解析:
错误答案为C,在对象生成的过程中,内存会给新对象的成员变量分配内存空间,对于成员函数则不会分配内存空间,其函数代码段存储在另一空间中,仅有一份,如果对象需要使用成用函数,将通过this(也只有一份)指向该对象,完成操作
具体存储方式详见:??https://blog.csdn.net/fuzhongmin05/article/details/59112081/??
二.静态成员变量(函数)定义
  static关键字修饰的成员变量和成员函数
特点
普通的成员变量每个对象各有一份,静态成员变量一共就一份,为所有对象所共享。
普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象
静态成员不需要通过对象就能访问


注意:
(1)sizeof运算符不会计算静态成员变量
(2)必须在定义类的文件中对静态成员变量进行一次说明或初始化
(3)在静态成员函数中,不能访问非静态成员变量(函数)(对象不明)
本质
静态成员变量(函数)本质上是全局变量(函数),对象存在与否,类的静态成员变量都存在
目的:
将和某些类紧密相关的全局变量和函数写到类中,看上去像一个整体,易于维护和理解
访问方式
方式一:
格式:类名::成员名
#include< iostream>
using namespace std;
class Studnet
public:
static int age; //静态成员变量
static Print()cout< < "Hello World!"< < endl; //静态成员函数
;
int main()
Student::Print(); //方式1
return 0;

方式二:
【C++学习之旅第二站(类和对象进阶)】格式:对象名.成员名
#include< iostream>
using namespace std;
class Studnet
public:
static int age; //静态成员变量
static Print()cout< < "Hello World!"< < endl; //静态成员函数
;
int main()
Student td;
td.Print(); //方式二
return 0;

方式三:
格式:指针-> 成员名
#include< iostream>
using namespace std;
class Studnet
public:
static int age; //静态成员变量
static Print()cout< < "Hello World!"< < endl; //静态成员函数
;
int main()
Student *td=& r; //并不具体某一对象
td-> Print(); //方式三
return 0;

方式四:
格式:引用.成员名
#include< iostream>
using namespace std;
class Studnet
public:
static int age; //静态成员变量
static Print()cout< < "Hello World!"< < endl; //静态成员函数
;
int main()
Student & td=r;
td.Print(); //方式四
return 0;

对象在生成时的初始化可能会使用构造函数或复制构造函数
三.成员对象和封闭类定义
有成员对象(类的成员为其他类的对象)的类成为封闭类
      任何生成封闭类对象的语句,都要让编译器明白,对象中的成员对象,是如何初始化的。
具体做法是:
通过封闭类的构造函数的初始化列表(可以为表达式,包含变量、函数)初始化
封闭类构造函数和析构函数的执行顺序
(1)封闭类对象生成时,先执行所有对象成员的构造函数,然后再执行封闭类的构造函数
(2)对象成员的构造函数调用次序和对象成员在类中的说明次序一致,与它们在成员函数初始化列表中出现的次序无关
(3)封闭类对象消亡时,先执行封闭类的析构函数,然后再执行成员对象的析构函数。
实际例子如下:
#include< iostream>
using namespace std;
class CTyre
public:
//构造函数
CTyre()cout< < "CTyre constructor"< < endl;
//析构函数
~CTyre()cout< < "CTyre destructor"&l

    推荐阅读