C++类中隐藏的六个默认函数
Test类中隐藏的六个默认的函数
class Test
{
public:
//默认的构造函数
Test();
//析构函数
~Test();
//拷贝构造函数
Test(const Test &t);
//赋值函数
Test& operator=(const Test &x);
//一般对象取地址函数
Test* operator&();
//常对象取地址函数
const Test* operator&()const;
private:
int data;
//int *data;
};
1.构造函数
作用:对象所在的内存空间做初始化 、给对象赋资源
特点:
- 可以重载 :可以根据实际需要进行缺省的、多参重载
- 不依赖对象:对象无法调用构造函数,只能在对象定义点被调用
//成员函数类外实现,需在函数名前指定作用域,否则编译器会认为在定义一个普通的函数
Test::Test() //类中默认的构造函数
{
}
//此外,构造函数可以支持重载,我们可以根据需要自己写一些构造函数
//需要注意的是,如果我们自己写了构造函数,那么编译器就不会提供默认的构造函数了
Test::Test(int d = 0 ) //缺省的构造函数
{
data = d;
}
Test::Test(int d = 0 ):data(d) //缺省的构造函数,用初始化器的方式初始化
{
}
两者初始化的区别在于,初始化器是真正意义上的初始化,它告诉编译器在实例化对象的时候以何种方式对成员赋值,而在前者的赋值规则写在了构造函数内部,是在已经生成了成员变量之后再进行的赋值操作。
初始化器实例:比如以下操作,成员变量定义为const类型,在C语言中const类型是一个常变量在定义的时候可以不初始化,而在C++中规定const类型为一个常量,定义时必须初始化。所以以下操作只能使用初始化器的方式初始化。
class Test
{
public:
Test(int a)
:ma(a)
{
//ma = a;
}
private:
const int ma;
};
此外,如果有多个成员变量需要使用初始化器的方式初始化,需要注意一点细节,初始化的顺序与成员变量的定义顺序相关。如以下程序,可以写成Test(int a):ma(mb), mb(a){}
或Test(int a):mb(a),ma(mb){}
因为成员变量的定义顺序为int mb; int ma;
,也就是说赋值顺序与初始化器无关,只与成员变量被定义的顺序有关。
class Test
{
public:
Test(int a):ma(mb), mb(a) //mb先被定义出来,先给mb赋值,再给ma赋值
{
}
Test(int a):mb(ma), ma(a) //error mb先定义出来,此时ma还未被定义,所以mb(ma)赋值无效,最终结果为,mb无效值,ma=a
{
}
void Show()
{
std::cout << "ma: " << ma << std::endl;
std::cout << "mb: " << mb << std::endl;
}
private:
int mb;
int ma;
};
2.析构函数
作用:释放对象所占的其他资源。
特点:
- 不可重载 : 对象销毁时会调用析构函数,并释放空间。
- 依赖对象:可用手动调用,但是不建议,因为对象销毁时会自动调用,如果手动调用可能会引起内存空间的重复析构导致程序崩溃
//默认的析构函数
Test::~Test()
{ //没有额外的资源,什么都不写
}
//如果程序中有额外的空间需要释放
class Test
{
public:
//构造函数
Test()
{
data = new int; //data指向一块堆区内存
}
//析构函数
~Test();
private:
int* data;
};
//析构函数
Test::~Test()
{
delete data; //把额外空间的释放写进析构函数
}
3.拷贝构造函数
作用:拿一个已存在的对象来生成相同类型的新对象
注意:类中提供的拷贝构造函数为一个浅拷贝类型,即如果成员变量中含有指针类型,它在进行拷贝构造的时候不会进行额外空间的开辟,最终会造成函数析构时的错误。
class Test
{
public:
//构造函数
Test()
{
data = new int; //data指向一块堆区内存
}
//拷贝构造函数
Test(const Test &t); //一定要传引用,否则在开辟形参的过程中会递归的调用拷贝构造函数来构造形参,而函数始终无法执行
private:
int* data;
};
//默认的拷贝构造函数
Test::Test(const Test &t)
{
data = t.data; //浅拷贝,只把现有的成员变量进行拷贝,没有对堆区内存进行拷贝,使多个对象的data指向了同一片堆区空间,在对象销毁时会造成空间的重复释放引发程序崩溃。
}
//拷贝构造函数
Test::Test(const Test &t)
{
data = new int; //如果是字符类型data = new char[strlen(t.data) + 1];
strcpy_s(data,sizeof(int), t.data);
}
4.赋值运算符的重载函数
作用:拿一个已存在的对象给相同类型的已存在对象赋值
实现步骤
- 自赋值判断
- 释放旧资源
- 生成新资源
- 赋值
class Test
{
public:
//构造函数
Test()
{
data = new int; //data指向一块堆区内存
}
//赋值函数
Test& operator=(const Test &x); //以自身类类型的引用的方式返回
private:
int* data;
};
//默认的赋值函数(浅拷贝)
Test& operator=(const Test &x)
{
if(this!=&x) //自赋值判断
{
data=x.data; //浅拷贝
}
return *this; //返回自身类类型的引用
}
//赋值函数(深拷贝)
Test& operator=(const Test &x)
{
if(this!=&x) //自赋值判断
{
delete[] data; //释放原资源,比如 a = 4, b = 5, a = b此时a放弃原先的资源 4
data = new int;
strcpy_s(data,sizeof(int), t.data);
}
return *this; //返回自身类类型的引用
}
5.一般对象取地址函数
//一般对象取地址函数
Test::Test* operator&()
{
return this;
}
6.常对象取地址函数
//常对象取地址函数
const Test::Test* operator&()const
{
return this;
}
C++类中隐藏的六个默认函数的更多相关文章
- 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘
孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...
- C++11 类的六个默认函数及其使用
六个默认函数: 构造函数(construct) 析构函数(destruct) 复制构造函数(copy construct) 赋值(assign) 移动构造函数(move construct) 移动赋值 ...
- C++类中的静态成员变量与静态成员函数
最近一直看c++相关的项目,但总是会被c++类中的静态成员变量与静态成员函数的理解感觉很是模糊,不明白为什么类中要是用静态成员变量.于是在网上搜集了一些资料,自己再稍微总结下. 静态成员的概念: 静态 ...
- C++ 类中的静态成员变量,静态成员函数
//类中的静态成员变量,静态成员函数 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; /* ...
- C++类中的静态成员变量和静态成员函数的作用
数据成员可以分为静态变量.非静态变量两种. 静态成员:静态类中的成员加入static 修饰符,即是静态成员,可以使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配 ...
- C++类中的静态成员变量与静态成员函数的使用
代码: #include <iostream> #include <string> #include <cstdio> using namespace std; c ...
- C# 类中隐藏基类方法和Partial
今天对于.NET开发人员来说最开心的事情莫过于微软搞开源了,这觉得是给搞.NET开发的长脸.虽然我是一个初学者,这无疑给我极大的学习动力.Fighting!!! 当一个类从父类继承了一个成员时,也就继 ...
- QWidget类中默认是忽略inputMethodEvent事件(要获取输入的内容就必须使用这个事件)
因为项目的需要以及主管的要求,准备将工程移植到Qt中,这样就可以比较容易的实现跨平台了.因为之前工程是在windows下开发的,第一个平台又是mobile所以除了底层框架之外其他的都是使用的windo ...
- C++类的默认函数
在C++中,一个类有八个默认函数: 默认构造函数: 默认拷贝构造函数: 默认析构函数: 默认重载赋值运算符函数: 默认重载取址运算符函数: 默认重载取址运算符const函数: 默认移动构造函数(C++ ...
随机推荐
- Qt:QWidget
0.说明 QWidget类是所有用户界面对象的基类. QWidget是用户界面的原子类.它接收鼠标.键盘和来自系统的其他事件,并在屏幕上将它们绘制出来.每个Widget都是矩形的,并按照Z-order ...
- Python:Scrapy(三) 进阶:额外的一些类ItemLoader与CrawlSpider,使用原理及总结
学习自:Python Scrapy 爬虫框架实例(一) - Blue·Sky - 博客园 这一节是对前两节内容的补充,涉及内容为一些额外的类与方法,来对原代码进行改进 原代码:这里并没有用前两节的代码 ...
- 前端js webuploader上传(导入)excel文件
项目开发中用到导入(上传)Excel文件 我使用的是百度的webuploader: 1:下载:http://fex.baidu.com/webuploader/(官方下载/示例) 2:使用Web Up ...
- WebSocket长连接
WebSocket长连接 1.概述 1.1 定义 1.2 原理 2.Django中配置WebSocket 2.1安装第三方法包 pip install channels 2.2 Django 中的配置 ...
- JAVA——选择,循环,顺序控制结构
目录 一.顺序控制 二.选择控制 2.1分支控制 2.1.1单分支 2.1.2双分支 2.1.3分支控制if-else 2.1.4嵌套分支 2.2switch分支结构 细节讨论 练习 题目1 题目2 ...
- LeetCode-103-二叉树的锯齿形层序遍历
二叉树的锯齿形层序遍历 题目描述:给定一个二叉树,返回其节点值的锯齿形层序遍历.(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行). 示例说明请见LeetCode官网. 来源:力 ...
- Python 细聊可以媲美 PS 的 PIL 图片处理库
1 . 前言 PIL 是 Python Image Library 的简称. PIL 库中提供了诸多用来处理图片的模块,可以对图片做类似于 PS(Photoshop) 的编辑.比如:改变图像大小.旋转 ...
- 亿图图示v9.2.0.0 官方中文版及破解激活补丁
介绍 亿图图示是一款由深圳市亿图软件有限公司开发的全类型,综合图形图表设计软件,解决跨平台,多领域,全终端的图形设计,图文混排和工程制图等需求.亿图图示是一款简单易用的快速制图软件,适合任何人绘制任何 ...
- Forms组件与钩子函数
目录 一:Forms组件 1.案例需求: 2.前端 3.后端 二:form表单前后端动态交互 1.form组件 2.为什么数据效验非要去后端 不能在前端利用js直接完成呢? 3.举例:购物网站 三:基 ...
- kafka 第一次小整理(草稿篇)————整理一下自己的认知
前言 简单整理一些自己使用kafka的一些感受. 正文 一切都要回到真实的世界上, 计算机世界只是真实事件的一个缩影. 计算机世界有一个重要的东西,那就是数据库. 数据库记录着真实世界发生了什么,准确 ...