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

Posted ITWEL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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指针_02

问题解析:

错误答案为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;

方式二:

格式:对象名.成员名

#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

以上是关于C++学习之旅第二站:类和对象进阶的主要内容,如果未能解决你的问题,请参考以下文章

打怪升级之小白的大数据之旅(六十一)<Hive旅程第二站:Hive安装>

小程序之旅——第二站()

Sql Server之旅——第二站 理解万恶的表扫描

C语言指针进阶第二站:指针数组!

我的OpenGL学习进阶之旅C++如何加载TGA文件?

我的OpenGL学习进阶之旅C++如何加载TGA文件?