当自己编写copying函数的时候要负责手动将每一个成员都拷贝

本文详细介绍了在C++中实现类的拷贝构造函数和赋值运算符的重要性,包括如何正确处理类的成员变量拷贝、父类成员变量拷贝及新增成员变量的拷贝。通过示例代码展示了如何避免编译器默认行为带来的问题,并强调了在继承类时手动实现拷贝构造函数和赋值运算符的必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结论1:如果自己编写copying函数则编译器就不会再为你自动生成,如果新追加一个成员变量,但是忘记在copying函数中追加这个变量的拷贝行为,这样编译器不会提示任何错误和警告信息,但是新变量不会被拷贝。因此如果追加新的成员变量,必须记住手动为该成员变量实现copying操作。

代码段1.1:Customer.h文件

#ifndef CUSTOMER_H
#define CUSTOMER_H

#include <string>
#include "Date.h"

class CCustomer
{
public:
    CCustomer(int month = 1, int day = 1, std::string name = "" ):m_name(name)
    {
        m_date.Setmonth(month);
        m_date.Setday(day);
    }
    CCustomer(const CCustomer& rhs);
    CCustomer& operator= (const CCustomer& rhs);
private:
    std::string m_name;
    CDate m_date;  //新加的就必须手动补上copying动作
    void logCall(const std::string& funcName);
};

#endif
View Code

代码段1.2:Customer.cpp文件

#include "Customer.h"
#include <iostream>

CCustomer::CCustomer(const CCustomer& rhs):m_name(rhs.m_name)/*,m_date(rhs.m_date) */ //此处加深理解,任何对象的private成员都可在本类中访问(为什么?作为下个课题)
{
    logCall("copy construct function");   //构造函数中也可以任意使用类的成员函数,不必是静态函数(为什么?作为下个课题)
}

CCustomer& CCustomer::operator=(const CCustomer& rhs)
{
    logCall("equal operator");
    m_name = rhs.m_name;
    /*m_date = rhs.m_date;*/
    return *this;
}

void CCustomer::logCall(const std::string& funcName)
{
    std::cout<<funcName<<std::endl;
}
View Code
代码段1.3:Date.h文件
#ifndef DATE_H
#define DATE_H

class CDate
{
public:
    CDate(int month = 1, int day = 1):m_month(month),m_day(day){}
    void Setmonth(int month){m_month = month;}
    void Setday(int day){m_day = day;}
private:
    int m_month;
    int m_day;
};

#endif
View Code

代码段1.4:main.cpp文件

#include "Customer.h"

int main()
{
    CCustomer c1(8,1,"lsy");
    CCustomer c2(c1);  //不会提示任何编译错误或警告,但是新追加的成员变量没有被复制
    CCustomer c3;
    c3 = c1;  //同上
    return 0;
}
View Code

结论2:如果一个类继承另一个类,编写copying函数时如果只copy了子类的成员变量而忽略了父类的成员变量,那么父类的成员变量不会被copy(因为copy构造函数也是一种构造函数,如果不手动写父类成员变量的拷贝,则copy构造函数会调用父类成员的默认构造函数等获取父类成员变量的默认值,赋值操作符也不会调用父类的赋值操作符。而只有编译器生成的copy构造函数和赋值操作符才调用父类的copy构造函数和赋值操作符),这时如果要让父类的成员变量实现copy,那么必须手动调用父类的拷贝构造函数和赋值运算符实现copying。

代码段2.1:PriorityCustomer.h文件

#ifndef PRIORITYCUSTOMER_H
#define PRIORITYCUSTOMER_H

#include "Customer.h"

class CPriorityCustomer:public CCustomer
{
public:
    CPriorityCustomer(int priority = 0, int month = 1, int day = 1, std::string name = ""): CCustomer(month,day,name),m_priority(priority){}
    CPriorityCustomer(const CPriorityCustomer& rhs);
    CPriorityCustomer& operator=(const CPriorityCustomer& rhs);
private:
    int m_priority;
};

#endif
View Code

代码段2.2:PriorityCustomer.cpp文件

#include "PriorityCustomer.h"

CPriorityCustomer::CPriorityCustomer(const CPriorityCustomer& rhs):m_priority(rhs.m_priority)/*,CCustomer(rhs)*/
{
    logCall("PriorityCustomer copy constructor");
}

CPriorityCustomer& CPriorityCustomer::operator=(const CPriorityCustomer& rhs)
{
    logCall("PriorityCustomer equal operator");
    m_priority = rhs.m_priority;
    /*CCustomer::operator=(rhs);*/
    return *this;
}
View Code

代码段2.3:main.cpp文件

#include "Customer.h"
#include "PriorityCustomer.h"

int main()
{
    //CCustomer c1(8,1,"lsy");
    //CCustomer c2(c1);  //不会提示任何编译错误或警告,但是新追加的成员变量没有被复制
    //CCustomer c3;
    //c3 = c1;  //同上

    CPriorityCustomer c1(2,8,1,"lsy");
    CPriorityCustomer c2(c1);
    CPriorityCustomer c3;
    c3 = c1;

    return 0;
}
View Code

结论3:虽然copy构造函数和赋值运算符代码相似,但是为了复用代码而互相调用是不可以的,因为copy构造函数是构造一个对象,赋值运算符是为一个对象赋值,二者截然不同,如果为了复用代码,可以将二者的共性抽出放到一个private成员函数中管理。

转载于:https://www.cnblogs.com/lisiyuannnn/p/4539704.html

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值