c++ 类的默认八种函数
c++ 类的默认八种函数
#define _CRT_SECURE_NO_WARNINGS #include <cstdio>
#include <cstdlib>
#include <cstring> #include <iostream>
#include <string> class MyClass
{
public:
MyClass(const char * str = nullptr); // 默认带参构造函数 // 默认构造函数指不带参数或者所有参数都有缺省值的构造函数
~MyClass(void); // 默认析构函数
MyClass(const MyClass &); // 默认拷贝构造函数
MyClass & operator =(const MyClass &); // 默认重载赋值运算符函数
MyClass * operator &(); // 默认重载取址运算符函数
MyClass const * operator &() const; // 默认重载取址运算符const函数
MyClass(MyClass &&); // 默认移动构造函数
MyClass & operator =(MyClass &&); // 默认重载移动赋值操作符函数 private:
char *m_pData;
}; // 默认带参构造函数
MyClass::MyClass(const char * str)
{
if (!str)
{
m_pData = nullptr;
}
else
{
this->m_pData = new char[strlen(str) + ];
strcpy(this->m_pData, str);
}
std::cout << "默认带参构造函数" << " this addr: " << this << std::endl;
} // 默认析构函数
MyClass::~MyClass(void)
{
if (this->m_pData)
{
delete[] this->m_pData;
this->m_pData = nullptr;
}
std::cout << "默认析构函数" << " this addr: " << this << std::endl;
} // 默认拷贝构造函数
MyClass::MyClass(const MyClass &m)
{
if (!m.m_pData)
{
this->m_pData = nullptr;
}
else
{
this->m_pData = new char[strlen(m.m_pData) + ];
strcpy(this->m_pData, m.m_pData);
}
std::cout << "默认拷贝构造函数" << " this addr: " << this << std::endl;
} // 默认重载赋值运算符函数
MyClass & MyClass::operator =(const MyClass &m)
{
if ( this == &m ) {
return *this;
} delete[] this->m_pData;
if (!m.m_pData)
{
this->m_pData = nullptr;
}
else
{
this->m_pData = new char[strlen(m.m_pData) + ];
strcpy(this->m_pData, m.m_pData);
} std::cout << "默认重载赋值运算符函数" << " this addr: " << this << std::endl;
return *this;
} // 默认重载取址运算符函数
MyClass * MyClass::operator &()
{
std::cout << "默认重载取址运算符函数" << " this addr: " << this << std::endl;
return this;
} // 默认重载取址运算符const函数
MyClass const * MyClass::operator &() const
{
std::cout << "默认重载取址运算符const函数" << " this addr: " << this << std::endl;
return this;
} // 默认移动构造函数
MyClass::MyClass(MyClass && m):
m_pData(std::move(m.m_pData))
{
std::cout << "默认移动构造函数" << std::endl;
m.m_pData = nullptr;
} // 默认重载移动赋值操作符函数
MyClass & MyClass::operator =(MyClass && m)
{
if ( this == &m ) {
return *this;
} this->m_pData = nullptr;
this->m_pData = std::move(m.m_pData);
m.m_pData = nullptr;
std::cout << "默认重载移动赋值操作符函数" << " this addr: " << this << std::endl;
return *this;
} void funA(MyClass a)
{
std::cout << "调用funA函数" << " param addr: " << &a << std::endl;
} void mytest1(void)
{
std::cout << "mytest1 >>>>" << std::endl;
MyClass myclass1; // 等价于 MyClass myclass1 = MyClass(); // 调用默认带参构造函数
myclass1 = MyClass(); // MyClass()为右值,需要右值引用 // 先调用默认带参构造函数,然后调用默认重载取址运算符函数,最后调用默认重载移动赋值操作符函数
std::cout << "<<<<< mytest1" << std::endl;
// 析构两次 1: myclass1 = MyClass()中的MyClass() 2: MyClass myclass1
} void mytest2(void)
{
std::cout << "mytest2 >>>>" << std::endl;
MyClass myclass1; // 等价于 MyClass myclass1 = MyClass(); // 调用默认带参构造函数
MyClass myclass2(myclass1); // 调用默认拷贝构造函数
myclass2 = myclass1; // myclass2为左值,所以此操作为赋值操作,会调用默认重载取址运算符const函数,然后调用默认重载赋值运算符函数
funA(myclass1); // 参数传值会导致赋值操作,会调用默认拷贝构造函数,然后funA函数调用默认重载取址运算符函数取得参数
funA(std::move(myclass1)); // funA函数的参数现为右值,会调用默认移动构造函数,然后funA函数调用默认重载取址运算符函数取得参数
// 在移动构造函数中对于基本类型所谓移动只是把其值拷贝,对于如string这类类成员来说才会真正的所谓资源移动
std::cout << "<<<<< mytest2" << std::endl;
} void mytest3(void)
{
std::cout << "mytest3 >>>>" << std::endl;
funA(MyClass()); // 会调用默认带参构造函数,生成该类的对象,然后funA函数调用默认重载取址运算符函数取得参数
std::cout << "<<<<< mytest3" << std::endl;
// 析构一次 1: funA(MyClass())中的MyClass()形成的对象,是在funA函数结束调用的时候,调用默认析构函数
} void mytest(void)
{
std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl; mytest1();
mytest2();
mytest3(); std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
} int main(int argc, char * argv[], char * envp[])
{
mytest(); system("pause");
return ;
}
<<<<<<<<<<<<<<<<<<<<<<<<<
mytest1 >>>>
默认带参构造函数 this addr: 0x7ffca6b2eed8
默认带参构造函数 this addr: 0x7ffca6b2eed0
默认重载取址运算符函数 this addr: 0x7ffca6b2eed0
默认重载移动赋值操作符函数 this addr: 0x7ffca6b2eed8
默认析构函数 this addr: 0x7ffca6b2eed0
<<<<< mytest1
默认析构函数 this addr: 0x7ffca6b2eed8
mytest2 >>>>
默认带参构造函数 this addr: 0x7ffca6b2eed8
默认拷贝构造函数 this addr: 0x7ffca6b2eed0
默认重载取址运算符const函数 this addr: 0x7ffca6b2eed8
默认重载赋值运算符函数 this addr: 0x7ffca6b2eed0
默认拷贝构造函数 this addr: 0x7ffca6b2eeb8
调用funA函数 param addr: 默认重载取址运算符函数 this addr: 0x7ffca6b2eeb8
0x7ffca6b2eeb8
默认析构函数 this addr: 0x7ffca6b2eeb8
默认移动构造函数
调用funA函数 param addr: 默认重载取址运算符函数 this addr: 0x7ffca6b2eeb0
0x7ffca6b2eeb0
默认析构函数 this addr: 0x7ffca6b2eeb0
<<<<< mytest2
默认析构函数 this addr: 0x7ffca6b2eed0
默认析构函数 this addr: 0x7ffca6b2eed8
mytest3 >>>>
默认带参构造函数 this addr: 0x7ffca6b2eed8
调用funA函数 param addr: 默认重载取址运算符函数 this addr: 0x7ffca6b2eed8
0x7ffca6b2eed8
默认析构函数 this addr: 0x7ffca6b2eed8
<<<<< mytest3
<<<<<<<<<<<<<<<<<<<<<<<<<
运行结果:
c++ 类的默认八种函数的更多相关文章
- Vue里面提供的三大类钩子及两种函数
在路由跳转的时候,我们需要一些权限判断或者其他操作.这个时候就需要使用路由的钩子函数. 定义:路由钩子主要是给使用者在路由发生变化时进行一些特殊的处理而定义的函数. 总体来讲vue里面提供了三大类钩子 ...
- Java大数类BigDecimal及八种舍入模式的介绍
BigDecimal的引入 在利用Java编程语言开发银行.金融类等需要对数值进行高精度计算的软件时,我们经常使用BigDecimal和BigInteger这两个大数据类,而不是常见的int.long ...
- Java常用类之【八种基本数据类型】
一.装箱和拆箱 装箱:将基本数据类型包装为对应的包装类对象 拆箱:将包装类对象转换成对应的基本数据类型 JDK5.0中为基本数据类型提供了自动装箱(boxing).拆箱(unboxing)功能 二.八 ...
- C++类的默认函数
在C++中,一个类有八个默认函数: 默认构造函数: 默认拷贝构造函数: 默认析构函数: 默认重载赋值运算符函数: 默认重载取址运算符函数: 默认重载取址运算符const函数: 默认移动构造函数(C++ ...
- Delphi过程函数传递参数的八种方式
今天一同事问我为什么有些过程函数里面有Var而有些没有,不解,遂到网上百度,得解.快哉,快哉. 在Delphi过程.函数中传递参数几个修饰符为Const.Var.Out.另一种不加修饰符的为默认按值传 ...
- JAVA四类八种基本数据类型
boolean类型 Boolean在内存中占用一个字节. 当java编译器把java源代码编译为字节码时,会用int或byte来表示boolean.在java虚拟机中,用整数零来表示false,用任意 ...
- Day1---Java 基本数据类型 - 四类八种 --九五小庞
一.Java四大数据类型分类 1.整型 byte .short .int .long 2.浮点型 float . double 3.字符型 char 4.布尔型 boolean 二.八种基本数据类型 ...
- C++中的类继承(2)派生类的默认成员函数
在继承关系里面, 在派生类中如果没有显示定义这六个成员 函数, 编译系统则会默认合成这六个默认的成员函数. 构造函数. 调用关系先看一段代码: class Base { public : Base() ...
- php八种常用函数
八种常用的数学函数: ① abs(x):求绝对值 ② ceil(x),floor(x):向上/下取最接近的整数 ③ cos(x),sin(x),tan(x):三角函数 ④ min(),max( ...
随机推荐
- MySql Jar 包下载
MySql JAR 包下载 我们要使用Spring 链接MySql 需要两个Jar 包 一个是C3p0 一个是MySql 的Connection Jar 包 C3p0: 进入下面的网址 h ...
- String类的一些常见的比较方法(4)
1:boolean equals(Object obj); //比较字符穿的内容是否相同 区分大小写的 2:boolean equalsIgnoreCase(String str); //比较字符穿的 ...
- 【个人笔记】《知了堂》express模块
NPM 包管理器 Node package module ==>简称npm 类似的bower 安装express 1.全局Npm install express -g 2.项目中安装 项目中 ...
- eclipse导入源码
1.window-----preferences 2.java---installed jres(点击不用展开)---选中使用的jar包-----editor 3.选中rt.jar ------sou ...
- org.springframework.core.io包内的源码分析
前些日子看<深入理解javaweb开发>时,看到第一章java的io流,发觉自己对io流真的不是很熟悉.然后看了下JDK1.7中io包的一点点代码,又看了org.springframewo ...
- android studio集成ijkplayer
介绍 ijkplayer是一款非常火的开源视频播放器,android和IOS通用.关于怎么编译怎么导入android Studio中自己的项目,其中坑很多,本篇记录下自己的操作记录.ijkplayer ...
- 云计算-openstack基础构架以及服务方式详解
一:什么是openstack 是Rackspace(美国航天局)和NASA(一家公司)共同发起的开源项目,他是一系列软件项目的组合. 这些项目是松耦合的关系,可以进行独立的安装,启动和停止,只有在必要 ...
- SQL server2005学习笔记(一)数据库的基本知识、基本操作(分离、脱机、收缩、备份、还原、附加)和基本语法
在软件测试中,数据库是必备知识,假期闲里偷忙,整理了一点学习笔记,共同探讨. 阅读目录 基本知识 数据库发展史 数据库名词 SQL组成 基本操作 登录数据库操作 数据库远程连接操作 数据库分离操作 数 ...
- VC维含义的个人理解
有关于VC维可以在很多机器学习的理论中见到,它是一个重要的概念.在读<神经网络原理>的时候对一个实例不是很明白,通过这段时间观看斯坦福的机器学习公开课及相关补充材料,又参考了一些网络上的资 ...
- 为什么ABAP开发者需要使用面向对象技术?
ABAP对面向对象的支持已有十多年的历史,然而在生产实践中,我们对这门技术的应用十分有限. 一方面,面向过程的惯性长期存在着:另一方面,对于大部分二次开发工作而言,似乎并没有足够的理由促使开发者使用面 ...