C++类与对象的详细说明2

目录
  • 类的默认成员函数
  • 构造函数
    • 概念
    • 特性
  • 析构函数
    • 概念
    • 特性
  • 拷贝构造函数
    • 概念
    • 特征
  • 赋值运算符重载
    • 运算符重载
    • 赋值运算符重载
  • 取地址及const取地址操作符重载
  • 总结

类的默认成员函数

每个类中,如果不主动实现默写特定函数,类中也会自动去生成这些函数,它们就是默认成员函数。默认成员函数分为六种,它们是特殊的成员函数,如果我们不实现,编译器会自己实现。

下面将对这些函数一 一进行介绍。

构造函数

概念

构造函数的作用即为初始化,相当于平时我们自己写的Init函数,但在对象实例化时会自动调用,以保证实例化对象一定初始化。

特性

(1)函数名与类名相同

如日期类Date,其构造函数名也为Date

(2)无返回值

以日期类为例,其构造函数的声明和定义可以写成如下样子:

class Date{public:Date(int year = 0, int month = 1, int day = 1);private:int _year;int _month;int _day;};class Date
{
public:
	Date(int year = 0, int month = 1, int day = 1);
private:
	int _year;
	int _month;
	int _day;
};
Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}

(3)对象实例化时编译器自动调用对应的构造函数

为了验证这一点,我们创建一个对象,但不对其进行其它操作:

int main()
{
	Date date1;
	return 0;
}

通过调试可以发现对象date1已经被自动初始化了。

(4)构造函数可以重载

(5)如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义,编译器将不再自动生成。

(6)无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。

针对第五点,我们不免会发出疑问,编译器自动生成的默认构造函数究竟干了什么呢?

首先,需要先了解C++把类型分为两类:内置类型(基本类型)和自定义类型。

内置类型就是C语言自带的类型,如int、char、double、指针、内置类型的数组;而自定义类型就是strucrt和class定义的类型。

编译器默认生成的构造函数,对于成员变量中的内置类型不做初始化,对于自定义类型成员变量则会调用它的默认构造函数初始化,如果没有默认构造函数则会报错。

析构函数

概念

析构函数的功能是完成对象中资源的清理。虚构函数会在对象的生命周期到了之后调用。

特性

(1)析构函数名是在类名前加上字符~。

(2)无参数无返回值。

日期类析构函数的声明可以写成如下形式:

~Date();

(3)一个类有且只有一个析构函数。若喂显式定义,系统会自动生成默认的析构函数。

(4)对象生命周期结束时,C++编译系统自动调用析构函数。 

对于编译器自动生成的默认析构函数,与构造函数类似,对于内置类型成员变量不做处理;对于自定义类型成员变量会去调用它的构造函数。

拷贝构造函数

概念

拷贝构造函数用于使用同类型对象去初始化实例对象。

特征

(1)拷贝构造函数是构造函数的一个重载形式。

(2)拷贝构造函数的参数只有一个且必须使用引用传参,使用传值的方式会引发无穷递归调用。

日期类拷贝构造函数的声明需要写成如下形式:

Date(Date& date);

为什么必须采用引用传参呢?引发无穷递归又是怎么一回事呢?

不妨来思考一下,传参实际上也是对内容进行临时拷贝,将实参传给形参本身就需要调用拷贝构造。由此一来,会导致不断调用拷贝构造,造成无穷递归调用。

(3)若未显式定义,系统会生成默认的拷贝构造函数了。

默认拷贝构造函数对于内置类型成员,会完成按字节序的拷贝(浅拷贝),如果需要深拷贝则需要自己写拷贝构造函数;对于自定义类型成员,则会调用它的拷贝构造函数。

所谓按字节序拷贝指将内存中的内容照搬照抄,复制过来。在一些情况下就会出错,如存放申请内存地址的指针,如果按字节序拷贝,会导致两个对象中的成员变量指向同一块空间,在析构时会导致同一块空间释放内存多次,引发错误。

赋值运算符重载

运算符重载

在谈及赋值运算符重载前,必须先来讲一讲运算符重载。

我们知道,对于int类型,是可以进行加减乘除等运算的。但对于自定义类型,能否实现加减乘除运算呢?这就需要运用到运算符重载了。

运算符重载是具有特殊函数名的函数。函数名字为:operator操作符(参数列表)

注意:一些运算符不支持重载,即:.*、::、sizeof、?:、.

以Date类==运算符重载为例,需要将函数作为成员函数,以便于访问成员变量:

class Date
{
public:
	Date(int year = 0, int month = 1, int day = 1);
	bool operator==(Date& date)const;
private:
	int _year;
	int _month;
	int _day;
};
bool Date::operator==(Date& date)const
{
	return _year == date._year
		&& _month == date._month
		&& _day == date._day;
}

赋值运算符重载

赋值运算符重载顾名思义,是对赋值运算符进行的重载,用于两个已经存在的对象进行赋值拷贝。

赋值运算符重载有四个要点:

(1)参数类型

(2)返回值

(3)检测是否自己给自己赋值

(4)返回*this,用于连续赋值

一个类如果没有显式定义赋值运算符重载,编译器会自己生成一个,对于内置成员,完成按字节序拷贝;对于自定义成员变量,会调用它的赋值运算符重载。

取地址及const取地址操作符重载

这两个运算符一般不需要重新定义,使用编译器生成的重载即可,只有特殊情况才需要重载,如不希望自己特定的内容被别人访问时。

总结

篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • C++类与对象的详细说明

    目录 类的引入 类的定义 1.声明和定义全部放在类体中 2.声明放在头文件,定义放在源文件中 类的访问限定符号及封装 访问限定符 封装 类的实例化 类对象模型 this指针 this指针的特性 总结 类的引入 在引入类之前,先来回忆一下C语言中的结构体.结构体是一种自定义类型,可以在其中定义变量,如我们所熟悉的日期结构体: struct Date { int year; int month; int day; }; 而在C++中,结构体被升级成了类,结构体中不仅可以定义成员变量,也可以定义成员函

  • C++类和对象之封装详解

    目录 封装的意义以及示例 访问权限 公共权限 public 保护权限 protected 私有权限 private struct 和 class的区别 成员属性私有化 案例1:设计立方体类 案例2:点和圆的关系 总结 封装的意义以及示例 封装是C++面向对象三大特征之一 封装的意义: 将属性和行为作为一个整体,表现生活中的事物将属性和行为加以权限控制 语法:class 类名{  访问权限 : 属性  /  行为 }: 类的对象的公共数据成员可以使用直接成员访问运算符 . 来访问. 示例1: 设计

  • C++学习笔记之类与对象详解

    目录 前言: 1.访问限定符: [问题]C++中 struct和class的区别是什么? 2.封装 [问题]在类和对象的阶段,我们只研究类的封装特性,那什么是封装呢? 3.类的定义与声明 [问题]函数调用的问题 4.类的作用域 5.类的实例化 6.类的分类 总结 前言: 1.C 语言是面向过程的,关注的是过程,分析出求解的步骤,通过函数逐步调用解决问题. 2.C++是基于面向对象的,关注的是对象,蒋一件事情拆分成不同的对象,靠对象之间的交互完成. 举个例子:外卖系统 面向过程是下单.接单.送餐的

  • C++类和对象之多态详解

    目录 多态基本概念和原理剖析 多态案例1 计算器类 纯虚函数和抽象类 多态案例2 制作饮品 虚析构和纯虚析构 多态案例3 电脑组装 多态基本概念和原理剖析 多态:多态是C++面向对象的三大特性之一.多态分为静态多态和动态多态. 静态多态:函数重载和运算符重载属于静态多态,复用函数名. 动态多态:派生类和虚函数实现运行时多态. 区别: 静态多态的函数地址早绑定,编译阶段确定函数地址. 动态多态的函数地址晚绑定,运行阶段确定函数地址. #include <iostream> using names

  • C++中的类与对象深度解析

    目录 初始化列表 引论 初始化列表 explicit关键字 引论 explicit关键字使用 static成员 友元 引论 友元 内部类 基础概念 内部类的使用 补充 析构顺序例题 总结 初始化列表 引论 //初始化列表的引出 class B { public: B() { cout << "我是B的构造函数" << endl; } private: int _b; }; class A { public: A() { cout << "我

  • C++初阶教程之类和对象

    目录 类和对象<上> 1. 类的定义 2. 类的封装 2.1 访问限定修饰符 2.2 类的封装 3. 类的使用 3.1 类的作用域 3.2 类的实例化 4. 类对象的存储 5. this 指针 5.1 this 指针的定义 5.2 this 指针的特性 类和对象<中> 1. 构造函数 1.2 构造函数的定义 2.2 构造函数的特性 2. 析构函数 2.1 析构函数的定义 3. 拷贝构函数 3.1 拷贝构造函数的定义 3.2 拷贝构造函数的特性 4. 运算符重载 4.1 运算符重载的

  • Java Scala数据类型与变量常量及类和对象超详细讲解

    目录 一.数据类型 二.变量和常量 三.类和对象 3.1 类 3.2 对象 3.3 伴生类和伴生对象 3.4 Scala的main函数只能写在object里 总结 一.数据类型 简记: 所有基础类型基本与Java的包装类等同,唯一有不同的Int(Scala),Integer(Java),注意这个就好 Unit, Null, Nothing, Any, AnyRef, AnyVal,这几个除了Null乍一眼会有些陌生,不要怕,上总结: 首先是层级图: 然后是表格: 补丁: 记住Any是所有类型的超

  • C++类与对象的详细说明2

    目录 类的默认成员函数 构造函数 概念 特性 析构函数 概念 特性 拷贝构造函数 概念 特征 赋值运算符重载 运算符重载 赋值运算符重载 取地址及const取地址操作符重载 总结 类的默认成员函数 每个类中,如果不主动实现默写特定函数,类中也会自动去生成这些函数,它们就是默认成员函数.默认成员函数分为六种,它们是特殊的成员函数,如果我们不实现,编译器会自己实现. 下面将对这些函数一 一进行介绍. 构造函数 概念 构造函数的作用即为初始化,相当于平时我们自己写的Init函数,但在对象实例化时会自动

  • 从C语言中读取Python 类文件对象

    问题 你要写C扩展来读取来自任何Python类文件对象中的数据(比如普通文件.StringIO对象等). 解决方案 要读取一个类文件对象的数据,你需要重复调用 read() 方法,然后正确的解码获得的数据. 下面是一个C扩展函数例子,仅仅只是读取一个类文件对象中的所有数据并将其输出到标准输出: #define CHUNK_SIZE 8192 /* Consume a "file-like" object and write bytes to stdout */ static PyObj

  • 简述 Python 的类和对象

    系列最后一篇来说说Python中的类与对象,Python这门语言是无处不对象,如果你曾浅要了解过Python,你应该听过Python是一种面向对象编程的语言,所以你经常可能会看到面向"对象"编程这类段子,而面向对象编程的语言都会有三大特征:封装.继承.多态. 我们平时接触到的很多函数.方法的操作都具有这些性质,我们只是会用,但还没有去深入了解它的本质,下面就介绍一下关于类和对象的相关知识. 封装 封装这个概念应该并不陌生,比如我们把一些数据封装成一个列表,这就属于数据封装,我们也可以将

  • Java 类与对象详细

    目录 1.类 2.对象 3.练习 4.练习答案 前言: 早期的Java语言,是面对过程的语言(面向过程指把一个场景分割成一个个的步骤研究),如今的Java已经是面对对象的语言(面向对象指把一个场景分割成一个个的对象研究).面向对象是相比面向过程有很多便利的地方,以后读者会慢慢感受到~ 那么,何谓对象呢?小编正在使用的电脑是一个对象,读者手中的手机是一个对象--对象,指[一个][具体的]物品或者事物(注意对象可以是抽象的东西). 每个对象都有其特征和用途,不同类型的对象特征和用途有所不同.我们把具

  • Python 类和对象详细介绍

    目录 对象 = 属性 + 方法 self是什么 公有和私有 继承 调用未绑定的父类方法 使用super函数 多重继承 组合 构造和析构 _ _init_ _(self[, …])构造方法 _ _new_ _(cls[, …])方法 _ _del_ _(self)析构方法 什么是绑定 对象 = 属性 + 方法 我们前面其实已经接触过封装的概念,把乱七八糟的数据扔进列表里面,这是一种封装,是数据层面的封装:把常用的代码段打包成一个函数,这也是一种封装,是语句层面的封装:现在我们要学习的对象,也是一种

  • 讲解C#面相对象编程中的类与对象的特性与概念

    类 "类"是一种构造,通过使用该构造,您可以将其他类型的变量.方法和事件组合在一起,从而创建自己的自定义类型.类就像一个蓝图,它定义类型的数据和行为.如果类没有声明为静态类,客户端代码就可以创建赋给变量的"对象"或"实例",从而使用该类.在对变量的所有引用都超出范围之前,该变量始终保持在内存中.所有引用都超出范围时,CLR 将标记该变量以供垃圾回收.如果类声明为静态类,则内存中只存在一个副本,并且客户端代码只能通过该类自身而不是"实例变

  • Hibernate核心类和接口的详细介绍

    一.hiobernate核心类和接口预览图 二.hibernate.properties 这个文件是以前老版本使用的 类似于hibernate.cfg.xml文件:作用和hibernate.cfg.xml一致. 三.hibernate.cfg.xml  (1)详细介绍 ①该文件主要用于指定各个参数,是hibernate核心文件 ②默认放在src目录下,也可以放在别的目录下. ③指定连接数据库的驱动.用户名.密码.url.连接池.. ④指定对象关系映射文件的位置. ⑤也可使用hibernate.p

  • 一篇文章搞懂Python的类与对象名称空间

    代码块的分类 python中分几种代码块类型,它们都有自己的作用域,或者说名称空间: 文件或模块整体是一个代码块,名称空间为全局范围 函数代码块,名称空间为函数自身范围,是本地作用域,在全局范围的内层 函数内部可嵌套函数,嵌套函数有更内一层的名称空间 类代码块,名称空间为类自身 类中可定义函数,类中的函数有自己的名称空间,在类的内层 类的实例对象有自己的名称空间,和类的名称空间独立 类可继承父类,可以链接至父类名称空间 正是这一层层隔离又连接的名称空间将变量.类.对象.函数等等都组织起来,使得它

随机推荐