C++类中的特殊成员函数示例详解
作者:tlanyan 发布时间:2023-11-07 13:02:08
前言
C++类中有几个特殊的非静态成员函数,当用户未定义这些函数时,编译器将给出默认实现。C++11前有四个特殊函数,C++11引入移动语义特性,增加了两个参数为右值的特殊函数。这六个函数分别是:
1、默认构造函数
默认构造函数指不需要参数就能初始化的构造函数。包含无参和所有参数有默认值两种类型的构造函数。
2、复制构造函数
复制构造函数指使用该类的对象作为参数的构造函数。可以有其他参数,但必须提供默认值。
3、复制赋值运算符
重载等号=,将该类的对象赋值给已定义对象。
4、析构函数
没啥可说的。
5、移动构造函数
C++11新增,该类的右值对象为参数的构造函数,其余同复制构造函数。
6、移动复制运算符
同复制赋值运算符,唯一不同是参数为右值。
看定义容易迷糊,上代码就会很清晰:
#include <iostream>
#include <string>
class Foo {
public:
std::string s;
// 默认构造函数
Foo() { std::cout << "default constructor" << std::endl; }
// 复制构造函数
Foo(const Foo& foo) { std::cout << "copy constructor" << std::endl; s = foo.s; }
// 复制赋值运算符
Foo& operator=(const Foo& foo) { std::cout << "copy assignment operator" << std::endl; s = foo.s; return * this;}
// 移动构造函数
Foo(Foo&& foo) { std::cout << "move constructor" << std::endl; s = std::move(foo.s); }
// 移动赋值运算符
Foo& operator=(Foo&& foo) { std::cout << "move assignment operator" << std::endl; s = std::move(foo.s); return *this;}
};
int main() {
Foo foo1;
Foo foo2(foo1);
foo1 = foo2;
Foo foo3(std::move(foo1));
foo2 = std::move(foo3);
}
用g++或者clang编译,加上-fno-elide-constructors -std=c++0x选项。执行程序输出如下:
default constructor
copy constructor
copy assignment operator
move constructor
move assignment operator
结果是我们预期的。需要注意的是Foo foo3 = foo1的形式会调用复制构造函数,不会调用复制赋值运算符。原因是Foo foo3 = xxx声明和定义一个新对象,而赋值是作用在已定义对象。移动赋值运算符同理。
C++11新增了=default和=delete函数修饰符,提示编译器使用默认或者删除默认的特殊函数。需要注意的是这两个修饰符只能修饰上述特殊函数,用户可以用其对特殊函数进行裁剪。一个例子:
struct Test {
// 使用默认构造函数
Test() = default;
// 删除复制赋值运算符
Test& operator=(const Test& test) = delete;
// 使用默认析构函数
~Test() = default;
};
参考
https://en.cppreference.com/w/cpp/language/member_functions
https://stackoverflow.com/questions/43349808/extended-lifetime-of-an-object-returned-from-function
来源:https://tlanyan.me/special-member-functions-in-cpp-class/


猜你喜欢
- 1.查找数据库中表的列名<pre name="code" class="html">St
- 本文实例为大家分享了Java使用组件编写窗口下载网上文件的具体代码,供大家参考,具体内容如下如图实现代码:package com.rain.
- java怎么判断三位数先定义个测试数字,如图然后可以把数字转换成字符串来判断它的长度是否为3,如图获取判断数字范围是否在100到1000之间
- 前言大家在初学java的时候,大部分的代码都是在控制台上运行的.可能大家辛辛苦苦写了几十行代码,最终就只是在控制台输出一个字符,这个时候,心
- 引入dll 本次程序中引入的是Spire.Pdf.dll,引入方法如下:【方法1】通过NuGet安装。可以在Visual Stud
- 安卓的开发从布局开始。安卓的界面编写也是使用xml进行布局的,一般如果熟悉了html界面的布局,那么很容易就能够理解安卓有关的布局了,这里介
- 本文实例讲述了Android开发实现的计时器功能。分享给大家供大家参考,具体如下:效果图:布局:三个按钮 加上一个Chronometer&l
- 客户端代码:/// <summary>/// 批量上传图片/// </summary>/// <param n
- 一、前言开发中经常要处理用户一些文字的提交,所以涉及到了敏感词过滤的功能,参考资料中DFA有穷状态机算法的实现,创建有向图。完成了对敏感词、
- 目录1、Java Application 源程序的主类是指包含有( )方法的类。2、如果定义一种表达式结构:(+ 6 3)的值为9,(- 6
- 本文以C#为例讲解木马程序的实现过程。要实现木马服务的程序,主要实现以下几个功能:后台的运行(隐藏技术),控制码的接收与注册表的修改,下面就
- 网络编程TCP实现聊天的前提还需要掌握IO流,话不多说,直接上代码!客户端:package com.kuang.lesson02;impor
- 本文实例为大家分享了java实现查找替换功能的具体代码,供大家参考,具体内容如下查找if(searchTxt.getText().equal
- Java 中的 BIO、NIO和 AIO 理解为是 Java 语言对操作系统的各种 IO 模型的封装。程序员在使用这些 API 的时候,不需
- 通过下面代码在构造函数中调用方法 SetShadow();即可实现无边框窗体的阴影效果了需要添加命名空间 using System.Runt
- kotlin基础教程之类和继承类声明使用class关键字声明类,查看其声明格式:: modifiers ("class"
- 前提:已经配置Zuul网关参考:https://www.jb51.net/article/182894.htm限流方式:1)nginx层限流
- 本文通过JavaMailSender实现邮箱注册验证中遇到的问题开始着手,给大家详细分析了其原理以及问题的解决办法。使用邮箱注册验证,我们需
- 在Spring中进行事务管理非常简单,只需要在方法上加上注解@Transactional,Spring就可以自动帮我们进行事务的开启、提交、
- RabbitMQ的示例,涉及到Direct、Fanout、Topic和Headers交换机以及普通队列、延迟队列和死信队列在pom.xml文