首页 > 其他分享 >调用拷贝构造函数的场景

调用拷贝构造函数的场景

时间:2023-06-18 23:46:24浏览次数:46  
标签:调用 函数 运算符 拷贝 构造函数 赋值

1.默认构造函数

默认构造函数是一个系统生成的,参数列表和函数体都为空的函数。
如果类中声明了默认构造函数(无论是否有参数),编译器便不再会为之生成隐含的构造函数。

2.析构函数

  • 析构函数的函数列表为空,因此不能实现重载。
  • 可以显式调用析构函数。例如可以通过对象名等进行调用,obj.~A();

参考文献:显式调用析构函数

3.拷贝构造函数

拷贝构造函数的参数必须是引用类型。参数是指针不会编译报错,但是3.1中的场景不能触发调用拷贝构造函数。

3.1 调用拷贝构造函数的3种场景

  • 用一个类的对象去初始化另一个类的对象时
Point a(1, 2);
Point b(a); // 调用复制构造函数
Point c = a; // 调用复制构造函数
  • 函数的形参是类对象,当调用函数,进行形参和实参结合时
void fun(Point obj) {}

int main() {
	Point a(1, 2);
    fun(a); // 调用复制构造函数
}
  • 如果函数的返回值是类对象,当函数执行完成返回调用者时

实际上,由于编译器的优化,可能不会调用。例如:gcc需要指定**-fno-elide-constructors**编译选项才会调用。

Point fun() {
	Point a(1, 2);
    return a; // 调用复制构造函数
}

b = fun();

4.赋值运算符

4.1 注意点

  • 拷贝构造函数必须以引用的方式传递参数,基本上都是传常量引用的方式传递函数参数。
  • 赋值运算符函数的返回值类型要声明为该类型的引用,并在函数结束前返回实例自身的的引用(*this只有返回一个引用,才能进行连续赋值。否则,如果函数的返回值是void,则应用该赋值运算符将不能进行连续赋值。假设有3个Person对象:p1、p2、p3,在程序中语句p1=p2=p3将不能通过编译。
  • 关于深拷贝和浅拷贝:当类有指针成员或有动态分配空间,都应实现自定义的拷贝构造函数。提供了拷贝构造函数,最后也实现赋值运算符。

4.2 和拷贝构造函数的区别

  • 区别:拷贝构造函数使用已有的对象创建一个新的对象,赋值运算符是将一个对象的值复制给另一个已存在的对象。区分是调用拷贝构造函数还是赋值运算符,主要是否有新的对象产生
#include <iostream>
using namespace std;

class A {
public:
    A(string str) : name(str) { cout << "construct " << name << endl; } // 构造函数
    A(const A &other) { // 拷贝构造函数
        name = "copy " + other.name;
        cout << name << endl;
    }
    A& operator = (const A &other) { // 赋值运算符重载
        name = "equal " + other.name;
        cout << name << endl;
        return *this;
    }

    string name;
};

void fun1(A obj) {}

A fun2() {
    A obj1("obj1");
    return obj1;
}

int main()
{
    A a("a");
    // 下面3行都是调用拷贝构造函数
    A b(a);
    A c = a;
    fun1(a);
    cout << "-----------" << endl;
    fun2();
    cout << "-----------" << endl;
    // 调用赋值运算符
    b = a;
}

/* 输出:
construct acopy a
copy a
copy a
-----------
construct obj1
copy obj1 (指定-fno-elide-constructors编译选项才有这一项输出)
-----------
equal a
*/

参考文献

1. C++ 拷贝构造函数和赋值运算符
2. C++ 拷贝构造函数和赋值运算符函数及其必要性和意义
3. 为什么拷贝构造函数自己的参数必须是引用类型 - 知乎

标签:调用,函数,运算符,拷贝,构造函数,赋值
From: https://www.cnblogs.com/devin1024/p/17490027.html

相关文章

  • linux java调用sh脚本
    1、2、importorg.jeecg.zhongyi.auto_dep.util.CommandStreamGobbler;importorg.jeecg.zhongyi.util.LogbackUtil;importorg.jeecg.zhongyi.util.vo.Result;importjava.io.IOException;importjava.io.InputStreamReader;importjava.util.LinkedList;importjava.......
  • C++构造函数
    RAIIResourceAcquisitionIsInitialization,资源获取即初始化这是一种解决资源管理问题的方法,将资源的有效期与持有资源的对象的生命期严格绑定,由对象的构造函数完成资源的分配,由析构函数完成资源的释放C++借助构造函数和析构函数,解决了传统的malloc&free和new&de......
  • Python调用外部系统命令
    利用Python调用外部系统命令的方法可以提高编码效率。调用外部系统命令完成后可以通过获取命令执行返回结果码、命令执行的输出结果进行进一步的处理。本文主要描述Python常见的调用外部系统命令的方法,包括os.system()、os.popen()、subprocess.Popen()等。本文分析python调用外......
  • 对象的finalize调用链和clone调用链一样,必须手工构造
    classA{publicA(){System.out.println("Aconstruct");}@Overridepublicvoidfinalize(){System.out.println("Afinalize");}}classBextendsA{String......
  • 后台用异步线程调用的场景与常用方式
    一.异步执行的场景:完成业务后,发短信、发邮件、微信公众号等消息推送提示的功能,可以采用异步执行。在导入数量量过大等情况下,可以使用异步导入的方式,提高导入时间等。...等等二.实现的方式:1.springboot中,进行线程池配置,然后用@Async标识异步执行方法即可,如下:(需要注意的@Enable......
  • Java对象拷贝MapStruct
    介绍编译期即可生成对象复制代码。简单理解,功能定位org.springframework.beans.BeanUtils。官网,GitHub-MapStruct。入门maven项目引入依赖:mapstruct:包含必要注解,如@Mappingmapstruct-processor:注解处理器,根据注解自动生成mapper实现<dependency><groupId>org.mapstruct</group......
  • 记录--封装一个通过js调用的全局vue组件
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助前言在使用vue项目编写的时候,不可避免的会碰到需要时jsapi来调用组件进行显示的情况例如饿了么elementui的Notification通知、Message消息提示等组件虽然已经提供了,但是由于api的限制,我们只能通过特定的参......
  • Python 深浅拷贝
    Python深浅拷贝一、数字、字符串对于数字和字符串而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。importcopy##########数字、字符串#########n1=123#n1="evescn"print(id(n1))###赋值##n2=n1print(id(n2))###浅拷贝##n2......
  • 【Azure 应用服务】Azure Data Factory中调用Function App遇见403 - Forbidden
    问题描述在AzureDataFactory(数据工厂)中,调用同在Azure中的FunctionApp函数,却出现403-Forbidden错误。截图如下:  问题解答访问AzureFunctionApp遇见403-Forbidden错误,这是因为FunctionApp启用了限制访问功能,在其中配置了允许访问的IP地址列表,而从ADF中发出的请求使用的I......
  • qt创建调用动态库、静态库
    参考 https://www.cnblogs.com/skynet/p/3372855.html---------------------------------------------windows下-------------------------------------------------------------1、创建动态库、静态库方法参考:https://blog.csdn.net/m0_67254672/article/details/123072198......