【C++】类和对象<上>(类的定义,类域,实例化,this指针)

大大大反派 2024-10-11 11:05:04 阅读 86

目录

一. 类的定义

【对比c】结构体和类的区别

1. 称呼:变量 or 对象? 

2. 类型:

3. 访问限定:

4. c和c++结构体使用

5. 相同点: 

二. 类域

三. 实例化

1. 1对N

2. 计算大小只考虑成员变量

3. 到此一游

四. this指针

this的隐藏使用

注意:

this作用:

题目深刻理解this 


一. 类的定义

< c++中,类可以用class关键词实现,也可以用结构体struct实现 >

以下是class关键词的使用

如下代码, class为定义类的关键字,Stack为你取的类的名字,{ }内为类的主体

<code>class Stack

{

//成员变量

int* array;

size_t capacity;

size_t top;

//成员函数

void Init(int capacity = 4)

{

}

};

注意一:也许会遇上如下初始化的时候,capacity(成员变量) = capacity(函数创建的临时变量)

区分方法:定义成员变量可以在变量前加标识符“_”

class Stack

{

//成员变量

//定义成员变量可以在变量前加标识符“_”

int* _array;//如 int* _array 或者 array_

size_t _capacity;//加标识符是为了方便区分如下函数Init的初始化谁是谁

size_t _top;

//成员函数

void Init(int capacity = 4)

{

//一目了然,左边是成员变量,右边是函数接收传参的临时变量

_capacity = capacity;

}

};

注意二

【对比c】结构体和类的区别

以下是我们定义数据结构中“栈”用结构体两种形式的代码

//定义栈的结构体

typedef int STDataType;

typedef struct Stack

{

STDataType* arr;

int capacity;

int top;

}ST;

//Stack类

class Stack

{

//成员变量

int* array;

size_t capacity;

size_t top;

}

1. 称呼:变量 or 对象? 

2. 类型:

结构体的类型是 struct Stack(除非你取typedef 类型名称)类的类型直接就是 Stack

3. 访问限定:

扩展知识:c++访问限定符

共有(public) :类外也可以访问(如也可以在main中使用)

私有(private):只允许类内访问

结构体默认公有(c++也可以对结构体进行自定义共有和私有)

默认私有(没加访问限定符的时候类可以自定义 共有(public) 和 私有(private)

结构体

4. c和c++结构体使用

c++比c语言多了可以在结构体里写函数 ,且c++的结构体不用typedf也能直接省略struct做类名 

c++创建结构体

5. 相同点: 

调用对象/函数  .

调用指针 ->

<code> Stack.Init(); 

ST.Init();

Stack->arr;

ST->arr;

二. 类域

.c++一共有四大域:函数局部域、全局域、命名空间域和类域。

而我们之前在类中定义的成员函数和成员变量,就属于类域

通俗说,不同类域相当于不同家族,不同家族里可以都叫“张伟”不会混,相同家族就有可能。

函数 声明定义分离 要 指定类域

声明与定义区分的根本是:是否有开辟空间

声明:系统未给开辟空间定义:系统给开辟了空间

头文件定义后,在源文件使用要声明类

格式:     函数返回类型 类名:: 函数名(传参列表)

                              void  Stack:: Init (int n)

举例来说 如下就是标准的类的声明和定义分离

在Stack.cpp文件中指定我们要查找的函数Init(),前面带上指定的类域

Stack.h

复习一下:(缺省参数在声明和定义都在的时候只能给声明,不能给定义) 

//这是你头文件定义的类的基本结构

class Stack

{

public:

void Init(int n = 4);//缺省参数在声明和定义都在的时候只能给声明,不能给定义

private:

int* _a;

int top;

int _capacity;

};

 Stack.cpp

为了让编译器找到类中的函数,我们需要在前面加上 Stack:: 指定类域

#include"Stack.h"

//我们在类外面定义函数

void Stack::Init(int n )

{

//...

}

三. 实例化

这是我之前写的博客内容

1. 1对N

一个类可以实例化多个对象

2. 计算大小只考虑成员变量

不包含成员函数

计算方式遵循内存对齐原则

内存对齐原则

3. 到此一游

当类中只有成员函数或者类为空类时,其所创建的对象大小为1字节,纯属占位作用

四. this指针

this的隐藏使用

代码引入

<code>#include <iostream>

using namespace std;

class MyClass

{

public:

MyClass(int a = 0, float b = 0, char c = 0)//构造函数,用于初始化对象的成员变量,后续会给大家介绍

{

_a = a;

_b = b;

_c = c;

}

void Print()

{

cout << _a << endl;

cout << _b << endl;

cout << _c << endl;

}

private:

int _a;

float _b;

char _c;

};

int main()

{

MyClass m = { 1,5.5,'w' };

m.Print();

}

如上print函数没有参数,为什么能准确传参?

实际上,这里的Print函数的参数的第一个位置,存在一个隐含的this指针

该函数调用当中的this指针指向的是对象m,自动访问其地址

注意:

形参和实参传参列表(this指针会自动在参数第一个位置生成)不可直接使用this,仅可在类的成员函数中使用。 

this作用:

1. 当我们需要使成员函数返回该对象的地址,就可以return this;

2. 当函数内的局部变量与类的成员变量名发生冲突时,就可以在类成员前加上this->,便于区分。

题目深刻理解this 

1. 以下代码的运行结果是? 

<code>#include <iostream>

using namespace std;

class MyClass

{

public:

void Print()

{

cout << "hehe" << endl;

}

private:

int _a;

};

int main()

{

MyClass* a = nullptr;

a->Print();

}

题目简单说,就是创建类指针a,并调用函数Print

答案正常运行,打印“hehe”。

解析:虽然使用了“->”,但是并没有对空指针a进行解引用,本质是将a传递给了形参this指针

没有解引用→没有访问成员变量,只打印了“hehe”,所以不会发生问题,程序正常运行。

疑问:为什么没有解引用a?)

(对象只存储成员变量的地址,不存储成员函数地址)

(因此print函数地址未存储,不会被对象解引,因此不出错)

2. 以下代码的运行结果是? 

#include <iostream>

using namespace std;

class MyClass

{

public:

void Print()

{

cout << _a << endl;

}

private:

int _a;

};

int main()

{

MyClass* a = nullptr;

a->Print();

}

答案运行崩溃。

 解析:函数内部访问成员变量_a,_a本质是由this指针解引用访问到的

出现空指针解引用的问题,运行崩溃。

希望对你有帮助



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。