当前位置: 首页 > news >正文

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

目录

一. 类的定义

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

1. 称呼:变量 or 对象? 

2. 类型:

3. 访问限定:

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

5. 相同点: 

二. 类域

三. 实例化

1. 1对N

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

3. 到此一游

四. this指针

this的隐藏使用

注意:

this作用:

题目深刻理解this 


一. 类的定义

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

以下是class关键词的使用

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

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. 相同点: 

调用对象/函数  .

调用指针 ->

   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的隐藏使用

代码引入

#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. 以下代码的运行结果是? 

#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”,所以不会发生问题,程序正常运行。

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指针解引用访问到的

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

希望对你有帮助


http://www.mrgr.cn/news/38482.html

相关文章:

  • 华为仓颉语言入门(7):深入理解 do-while 循环及其应用
  • 区块链可投会议CCF C--FC 2025 截止10.8 附录用率
  • 【hadoop安装】
  • 软件设计——随手笔记
  • Feign:服务挂了也不会走fallback
  • PY32F002B
  • 「JavaScript深入」彻底搞懂JS原型与原型链
  • 繁体字能申请注册商标吗?
  • 【AIGC】ChatGPT提示词助力自媒体内容创作升级
  • 支付宝远程收款api之小荷包跳转码
  • 黑神话悟空小西天
  • Scrapy入门
  • 网络编程(Java)
  • 用Uvicorn 构建和部署高性能的异步 Web服务器@python
  • ViTamin——视觉-语言时代的可扩展视觉模型设计
  • SPI驱动学习七(SPI_Slave_Mode驱动程序框架)
  • 大语言模型知识点分享
  • 【C++】C++的Vector使用和实现
  • 【ESP32】Arduino开发 | I2C控制器+I2C主从收发例程
  • 解决在vue项目中index.html中直接引入Cesium.js时候报错:Cesium is not defined