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.构造函数

作用:对象所在的内存空间做初始化 、给对象赋资源

特点

  1. 可以重载 :可以根据实际需要进行缺省的、多参重载
  2. 不依赖对象:对象无法调用构造函数,只能在对象定义点被调用
//成员函数类外实现,需在函数名前指定作用域,否则编译器会认为在定义一个普通的函数
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.析构函数

作用:释放对象所占的其他资源。

特点

  1. 不可重载 : 对象销毁时会调用析构函数,并释放空间。
  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.赋值运算符的重载函数

作用:拿一个已存在的对象给相同类型的已存在对象赋值

实现步骤

  1. 自赋值判断
  2. 释放旧资源
  3. 生成新资源
  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++类中隐藏的六个默认函数的更多相关文章

  1. 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘

    孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...

  2. C++11 类的六个默认函数及其使用

    六个默认函数: 构造函数(construct) 析构函数(destruct) 复制构造函数(copy construct) 赋值(assign) 移动构造函数(move construct) 移动赋值 ...

  3. C++类中的静态成员变量与静态成员函数

    最近一直看c++相关的项目,但总是会被c++类中的静态成员变量与静态成员函数的理解感觉很是模糊,不明白为什么类中要是用静态成员变量.于是在网上搜集了一些资料,自己再稍微总结下. 静态成员的概念: 静态 ...

  4. C++ 类中的静态成员变量,静态成员函数

    //类中的静态成员变量,静态成员函数 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; /* ...

  5. C++类中的静态成员变量和静态成员函数的作用

    数据成员可以分为静态变量.非静态变量两种. 静态成员:静态类中的成员加入static 修饰符,即是静态成员,可以使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配 ...

  6. C++类中的静态成员变量与静态成员函数的使用

    代码: #include <iostream> #include <string> #include <cstdio> using namespace std; c ...

  7. C# 类中隐藏基类方法和Partial

    今天对于.NET开发人员来说最开心的事情莫过于微软搞开源了,这觉得是给搞.NET开发的长脸.虽然我是一个初学者,这无疑给我极大的学习动力.Fighting!!! 当一个类从父类继承了一个成员时,也就继 ...

  8. QWidget类中默认是忽略inputMethodEvent事件(要获取输入的内容就必须使用这个事件)

    因为项目的需要以及主管的要求,准备将工程移植到Qt中,这样就可以比较容易的实现跨平台了.因为之前工程是在windows下开发的,第一个平台又是mobile所以除了底层框架之外其他的都是使用的windo ...

  9. C++类的默认函数

    在C++中,一个类有八个默认函数: 默认构造函数: 默认拷贝构造函数: 默认析构函数: 默认重载赋值运算符函数: 默认重载取址运算符函数: 默认重载取址运算符const函数: 默认移动构造函数(C++ ...

随机推荐

  1. VUE3 之 使用标签实现动画与过渡效果(下) - 这个系列的教程通俗易懂,适合新手

    1. 概述 毛毛虫效应: 有这样一个实验,将许多毛毛虫放在一个花盆边缘,使它们首尾相接,围成一个圈.然后在离花盆很近的地方撒了一些毛毛虫的食物. 此时,毛毛虫并不会向食物的方向爬去,而是在花盆边缘,一 ...

  2. JAVA_Scanner 键盘输入

    键盘输入语句 介绍:在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取.Input.java , 需要一个 扫描器(对象), 就是 Scanner 步骤: 导入该类的所在包, java.u ...

  3. SQL实现一年中每个日期剔除节假日和星期天之后的五个日期是多少

    最近公司OA系统的需求,实现一年中每个日期剔除节假日和星期天之后的五个日期是几号,每个日期都要跳过节假日和星期天,当时是真的慌了,郁闷了一天,后来半夜忽然来灵感,想想还是可以实现. 需要做一张节假日的 ...

  4. Higncharts 制作

    <html> <head> <meta charset="UTF-8" /> <title>Highcharts 教程 | 菜鸟教程 ...

  5. MySQL Performance Schema详解

    MySQL的performance schema 用于监控MySQL server在一个较低级别的运行过程中的资源消耗.资源等待等情况. 1 performance schema特点 提供了一种在数据 ...

  6. iCloud开发: key-value Storage,CloudKit,iCloud Documents

    目录 iCloud开发 iCloud三种类型的存储方式 项目配置 1.iCloud 官网配置 2.本地Xcode配置 注意事项 一.key-value storage 1.获取默认store 2.写入 ...

  7. kkFileView部署到windows服务出现问题解决

    1.部署之后执行出现api-ms-win-crt-runtime-l1-1-0.dll丢失的办法 微软官网下载vc_redist.x64.exe vc_redist.x86.exe 64位的操作系统需 ...

  8. Airtest安装与简介

    一:简介 什么是Airtest 网易的airtest其实是个测试套件,由Airtest框架.poco框架.airtestIDE 组成. Airtest框架 基于图像识别的自动化测试框架,是网易自己团队 ...

  9. springcloud报错-Ribbon整合Eureka,出现 No instances available for XXX 异常

    RestTemplate注入有问题 新版的需要这样注入: @Bean @LoadBalanced RestOperations restTemplate(RestTemplateBuilder bui ...

  10. Java基础——日期类Date

    一.概述 date代表一个特定的时间,精确到毫秒 二.构造方法 方法名 说明 public Date() 分配一个Date对象,并初始化,以便它代表被分配的时间,精确到毫秒 public Date(l ...