C++的类和对象

article/2025/9/20 21:41:12

目录

C++面向对象的三大特性:封装、继承、多态

封装

构造函数和析构函数

构造函数的分类与调用

深拷贝与浅拷贝

类对象作为类成员

静态成员

成员变量和成员函数是分开存储的

const修饰成员函数

友元

运算符重载

继承

多态


C++面向对象的三大特性:封装、继承、多态

C++认为万事万物皆可为对象,对象有其属性和行为

具有相同性质的对象,可以抽象为类

封装

类在设计时,可以把属性和行为放在不同的权限下,加以控制

  • public:公共权限,类内可访问、类外可访问,
  • protected:保护权限,类内可访问、类外不可访问,儿子可以访问父亲的保护内容
  • private:私有权限,类内可访问、类外不可访问,儿子不可以访问父亲的私有内容

struct和class的区别在于

  • struct的默认权限是public
  • class的默认权限是private

成员属性一般设置为私有,好处是

  • 可以自己控制读写权限
  • 对于写,可以检测数据的有效性

构造函数和析构函数

  • 构造函数:主要用于创建对象时为成员属性赋值,由编译器自动调用
  • 析构函数:主要用于对象销毁前的自动调用,执行一些清理工作

构造函数:类名(参数) {}

  • 没有返回值,也不写void
  • 函数名称与类名相同
  • 构造函数可以有参数,可以重载
  • 程序在创建对象的时候会自动调用构造函数,而且只会调用一次

析构函数:~类名() {}

  • 没有返回值,也不写void
  • 在构造函数名字前面加上“~”
  • 不可以有参数,不会有重载的情况
  • 在对象销毁前自动调用,而且只会调用一次

构造函数的分类与调用

  • 按参数分为:有参构造、无参构造
  • 按类型分为:普通构造、拷贝构造(传入对象)
  • 三种调用方法:括号法、显示法、隐式转换法

括号法:

  • Person p1;      //默认构造函数调用
  • Person p2(10);      //有参构造函数
  • Person p3(p2);      //拷贝构造函数
  • 调用默认构造函数时,不要加(),若添加会被编译器认为是一个函数的声明

显示法:

  • Person p1;      //默认构造函数调用
  • Person p2 = Person(10);      //有参构造函数
  • Person p3 = Person(p2);      //拷贝构造函数
  • 形如Person(10)的对象,称为匿名对象,当前行执行后系统会自动回收

隐式转换法:

  • Person p4 = 10;     //有参构造函数
  • Person p5 = p4;      //拷贝构造函数

拷贝构造函数的调用时机通常有:

  • 使用一个已经创建好的对象来初始化一个新对象
  • 值传递的方式给函数参数传值(拿到传入的参数会进行拷贝)
  • 以值方式返回局部对象(局部函数return出来的其实是拷贝数据)

深拷贝与浅拷贝

  • 浅拷贝:简单的赋值拷贝操作
  • 深拷贝:在堆区重新申请空间,进行拷贝操作
  • 如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区的问题

类对象作为类成员

  • C++类中的成员可以是另一个类的对象,我们称该成员为对象成员
  • 当其他类对象作为本类成员,构造时先构造类对象,再构造自身
  • 析构时先析构自身,再析构类对象

静态成员

静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员

静态成员分为

静态成员变量

  • 所有对象共享一份数据
  • 在编译阶段分配内存
  • 类内声明,类外初始化
  • 可以直接通过类名访问

静态成员函数

  • 所有对象共享一个函数
  • 静态成员函数只能访问静态成员变量
  • 可以直接通过类名访问
  • 可以访问静态成员变量,不可以访问非静态成员变量

成员变量和成员函数是分开存储的

  • 空对象占用空间为:1
  • 只有非静态成员变量属于类的对象上
  • 其他成员不属于类的对象上

非静态成员函数如何区分哪个对象调用自己?通过this指针解决

this指针指向被调用的成员函数所属的对象,常见用途:

  • 当形参和成员变量同名,可用this指针来区分
  • 在类的非静态成员函数中返回对象本身,可使用return *this

const修饰成员函数

常函数

  • 成员函数前加上const后,我们称其为常函数
  • 常函数内不可以修改成员属性
  • 成员属性声明时加关键字mutable,在常函数中依然可以修改

常对象

  • 声明对象前加上const,我们称其为常对象
  • 常对象只能调用常函数

友元

  • 友元的目的是让一个函数或者类访问另一个类中的私有成员
  • 友元的关键字为friend

友元函数的三种实现

  • 全局函数做友元
  • 类做友元
  • 成员函数做友元

运算符重载

  • 定义:对已有运算符重新定义,赋予另一种功能,以适应不同的数据类型
  • 成员函数重载,本质是p1.operator(p2)
  • 全局函数重载,本质是operator(p1,p2)
  • 左移运算符<< 只能利用全局运算符重载,配合友元可以实现输出自定义数据类型
ostream & operator<<(ostream& out,Person p){out << "a:" << p.m_a << "b:" << p.m_b ;return out;
}
  • 自增运算符++ 分为前置和后置,重载实现如下
    //重载前置++MyInteger& operator++() {m_num++;return *this;  }//重载后置++//int是占位参数,用于区分前置后置MyInteger& operator++(int) {MyInteger temp = *this;m_num++;return temp;}
  • 赋值运算符= 重载实现
Person& operator=(Person &p){//编译器提供的是浅拷贝,在析构时会出现问题//应该先判断是否有属性在堆区,如果有先释放再深拷贝if(m_Age != NULL){delete m_Age;m_Age = NULL;}//深拷贝m_Age = new int(*p.m_Age);//返回对象本身return *this;
}
  • 关系运算符重载
  • 函数调用运算符重载(仿函数,可以实现匿名对象调用)

继承

  • 好处:减少重复代码
  • 语法:class 子类 : 继承方式 父类
  • 子类也称派生类,父类也称基类

成员属性的继承

  • 父类中所有非静态成员属性都会被子类继承下去
  • 父类中私有成员属性是被编译器给隐藏了,因此访问不到,但确实是继承下去了的

构造与析构顺序

  • 先构造父亲,后构造儿子;析构相反

同名成员处理

  • 如果想访问父类中被隐藏的同名成员函数,需要加作用域 Base::

多继承语法

  • 语法:class 子类: 继承方式 父类1 , 继承方式 父类2
  • 当父类中出现同名成员,需要加作用域区分

菱形继承

在这里插入图片描述

  • 两个派生类继承同一个基类,又有某个类同时继承两个派生类
  • 二义性、数据冗余、使用不便

虚继承 virtual

在这里插入图片描述

  • 采用虚继承可以解决菱形继承问题
  • 虚继承后,继承类只会存储vbptr,意为虚基类指针,指向的是虚基类表
  • 虚基类表中存储了被继承类的地址偏移量
  • 通过这一偏移量,可以拿到被继承类中的数据

多态

  • 静态多态:函数重载 和 运算符重载属于静态多态,复用函数名
  • 动态多态:派生类和虚函数实现运行时多态

两种多态的区别

  • 静态多态的函数地址早绑定——编译阶段确定函数地址
  • 动态多态的函数地址晚绑定——运行阶段确定函数地址

动态多态满足条件

  • 有继承关系
  • 子类重写父类的虚函数

动态多态的使用

  • 父类指针或引用指向子类对象

动态多态的原理

 多态的好处

  • 组织结构清晰
  • 可读性强
  • 利于扩展和维护

纯虚函数

  • 在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容
  • 因此可以将虚函数改为纯虚函数:virtual 返回值类型 函数名 (参数列表) = 0;
  • 当类中有了纯虚函数,该类也被称为抽象类

抽象类

  • 抽象类无法实例化对象
  • 子类必须重写抽象类中的纯虚函数,否则也是抽象类

虚析构

  • 可以解决父类指针释放子类对象时不干净的问题
  • 如果子类中没有堆区数据(new),可以不写虚析构

纯虚析构

  • virtual ~类名() = 0;
  • 需要在类外实现
  • 有纯虚析构的函数也是抽象类,无法实例化对象


http://chatgpt.dhexx.cn/article/ITYEQ1Pg.shtml

相关文章

java实例和对象对象的区别_java中实例与对象的区别和联系

对象是抽象的说法&#xff0c;你可以把它看作一个符合它自身定义的所有实例的代表&#xff0c;而实例则是对象的现实体现。 你可以说一个实例是一个对象&#xff0c;但你不能说一个对象是一个实例。因为定义对象时只是把自身的规则和逻辑定义好&#xff0c;实例可以通过输入不同…

怎么来理解java类和对象的区别

对象在需求中的使用 在具体问题中如何使用面向对象去分析问题&#xff0c;和如何使用面向对象。 以把大象装冰箱为例进行分析&#xff1a;在针对具体的需求&#xff0c;可以使用名词提炼的办法进行分析&#xff0c;寻找具体的对象。 需求&#xff1a;把大象装冰箱里 对象&…

C++类对象和类指针的区别

好奇这个&#xff0c;所以参考了一些帖子&#xff0c;写下心得。 一篇转载率较高的帖子&#xff1a;C 类对象和 指针的区别 大佬都不贴结果。。。。所以这里我给出代码和结果&#xff1a; #include<iostream> using namespace std;class Test{ public:int a;Test(){a …

Java中类和对象的区别

一、类和对象 1、类 类的理解 类是对现实生活中一类具有共同属性和行为的事物的抽象类是对象的数据类型&#xff0c;类是具有相同属性和行为的一组对象的集合简单理解&#xff1a;类就是对现实事物的一种描述 类的组成 属性&#xff1a;指事物的特征&#xff0c;例如&#xff…

安装svn 汉化包 也不能设置中文

(以下为亲测!) 汉化包地址:https://osdn.net/projects/tortoisesvn/storage 进入地址之后:选择对应版本-->>Language Packs-->>选择中文包 问题: 已经安装svn汉化包,但是不能设置为中文. 解决: 确保汉化包版本对应svn版本.如果汉化包版本已经对应svn版本,则把…

SVN汉化失败的原因及解决方案(通过SVN官网下载SVN和相应的汉化包)

1、没删除SVN根目录语言包里的所有文件 2、汉化包没放在SVN根目录的语言文件夹下安装 3、SVN版本和汉化包版本不一致 首先看自己电脑上安装的svn是什么版本&#xff1a; 比如我的就是 TortoiseSVN 1.11.1&#xff0c;那我就要找TortoiseSVN 1.11.1对应的TortoiseSVN 1.11.1l…

Tortoise SVN 汉化(官网下载汉化包)

&#xff08;本操作是已经下载Tortoise SVN后 &#xff0c;通过官网下载汉化包进行的操作&#xff09; 1、首先进入到官网 https://tortoisesvn.net/downloads.html 2、进入到官网首页&#xff0c;点击Translations 3、进入到翻译页面&#xff0c;点击download 4、进入到下…

window eclipse快速导入svn项目以及软件汉化

刚入职新公司&#xff0c;之前几家公司使用得IDE跟代码管理是idea跟gitlab,公司内sap/erp系统&#xff0c;立项时间较早&#xff0c;使用得是eclipsesvn。 进行导入项目之前&#xff0c;英语水平较差得得同学&#xff0c;可以将软件先进行快速汉化 1、如图 2、在弹出得输入框中…

关于svn汉化包安装无效的解决办法

下载svn汉化包要和对应的svn客户端版本对应&#xff0c;否则安装无效&#xff0c; 在安装前要想将svn安装目录下的languages目录下的文件全部删除 还有一点要注意的是 汉化包安装要放在svn安装目录下进行安装&#xff0c;它才能正常汉化 安装完后就可以选择语言了

SVN安装包汉化VS插件

一.SVN客户端安装 首先下载SVN 地址&#xff1a;https://tortoisesvn.net/downloads.zh.html 根据版本进行选择 安装直接下一步下一步默认文件夹就好了 安装完成右键就会有二个多出来的菜单 都是英文不是很方便 二.语言转换 在下载SVN的下面就有语言包可以一起下载 进行语…

svn汉化插件安装步骤

1.svn安装好之后&#xff0c;查看svn安装的版本&#xff0c;比如我的svn是1.9.7.27907版本 64位的。 2.去svn官网&#xff1a;https://tortoisesvn.net/ 3.将网站显示中文版&#xff0c;便于查看&#xff1a; 4.点击“下载”&#xff1a; 5.看版本一致&#xff0c;往下拉&#…

SVN基本使用1

一、什么是SVN 代码管理工具 能记住每次的修改 查看所有的修改记录 恢复到任何历史版本 恢复已删除的文件 二、跟Git比 SVN使用简单上手快支持中文(Git较为复杂不支持中文) 目录级权限控制(Git没有),企业级安全必备 可以单独子目录checkOut(Git只能将整个仓库),可以减少…

Svn下载及安装(附带汉化包安装)

1、访问Svn官方网站&#xff1a;https://tortoisesvn.net 2、找到需要下载的版本类型 3、下载完成后一直下一步安装即可 4、Svn安装包下载 5、下载完成之后&#xff0c;一直下一步即可 6、安装好之后&#xff0c;在任意空白位置 —> 右击 —> 选择TortoiseSVN —> …

Windows安装SVN客户端并汉化

1、下载 https://tortoisesvn.net/downloads.zh.html 2、安装 鼠标双击 3、汉化 汉化包下载地址&#xff1a;https://tortoisesvn.net/downloads.zh.html 鼠标双击汉化包 点击svn的各种界面查看是否汉化成功

SVN下载以及汉化安装包的使用

前言&#xff1a; SVN&#xff08;subversion&#xff09;是一个开放源代码的版本控制系统&#xff0c;通过采用分支管理系统的高效管理&#xff0c;实现资源的共享&#xff0c;实现集中式的管理。 SVN下载&#xff1a; 第一步&#xff1a; https://tortoisesvn.net/downloads…

SVN汉化以及简单的使用

一、SVN的安装以及汉化 1.下载SVN的安装包以及汉化包&#xff1b; 2.先安装SVN汉化包&#xff0c;然后安装SVN的程序软件&#xff0c;都安装完成后&#xff0c;在空白位置右击选择设置&#xff0c;在language中选择中文简体&#xff0c;点击确认即可&#xff1b; 至此&#xff…

安装svn和安装svn汉化语言包

svn官网&#xff1a; https://tortoisesvn.net/downloads.zh.html 这里下安装包 和语言包&#xff0c;以此安装即可&#xff1b;都默认安装就行了

解决SVN汉化不成功问题,下载历史版本

考虑是不是版本不一致问题。如果想汉化&#xff0c;最好在安装svn都下载了&#xff0c;直接安装。免得像我一样过了好久还得找对应版本安装≥﹏≤ 查看自己安装的svn历史版本 在官方网站找到对应的版本汉化包 点击版本连接找到对应版本–选择汉化包–找到中文点击下载&#…

SVN汉化包安装方法

注意&#xff1a;下载的svn汉化包必须与svn客户端版本对应&#xff0c;否则安装无效 1、首先安装svn客户端&#xff0c;然后将svn汉化包放在svn的安装目录下。 2、安装svn汉化包之前&#xff0c;将svn安装目录下的languages目录下的文件全部删除 。 3、svn汉化包安装完成后&am…

svn汉化失败解决方法

前提:别人已经安装好了svn,但是没有汉化,我随意找了一个汉化包,运行安装后,并没有汉化 成功过程: 1、找到一个文件,右击看到svn(已经安装了svn)&#xff0c;选中"关于"&#xff0c;看你到svn的版本&#xff0c;红框的就是我的版本 2、在svn官网上找到对应的汉化包&…