C++ 中拷贝构造函数和赋值运算符的区别

本文探讨了C++中拷贝构造函数与赋值运算符的重要性,并通过具体示例展示了如何实现二者,避免因资源重复引用导致的问题。通过正确使用拷贝构造函数和赋值运算符,可以确保对象状态的一致性和内存资源的有效管理。

顾名思义,拷贝构造函数就是用另外一个对象去初始化一个对象,
而赋值是对已构造的(被初始化的)对象重写(赋值)
A a;
A b(a);A c = a;都是调用的拷贝构造函数

A d;
b = d;c = d;都是调用的赋值操作符

注释:

用一个已存在的对象去 构造一个不存在的对象(构造之前不存在),就是拷贝构造.
用一个已存在的对象去 覆盖另一个已存在的对象,就是赋值运算.

1. 为什么要使用拷贝构造函数?

    请看以下程序,我们创建了两个Node对象,第二个对象的创建直接拷贝第一个已创建的对象。然后我们想修改第二个对象node2的name字段,采用库函数strcpy()。但是并没有得到预期的结果。
   

#include < iostream.h >
#include
<string .h >

struct  Node
{
    
char *name;
    
int age;
    Node(
char *n=""int a=0)
    
{
        name
=new char[strlen(n)+1];
        strcpy(name, n);
        age
=a;
    }

}
;

void  main()
{
    Node node1(
"Roger"20);
    Node node2(node1);
//创建了对象node1的逐位复制件,且包含了一个指向对象node1的指针

    strcpy(node2.name, 
"Wendy");//修改node2的name的同时,node1的name也被修改
    node2.age=30;

    cout
<<node1.name<<' '<<node1.age<<' '
        
<<node2.name<<' '<<node2.age<<endl;
}


运行结果:
Wendy 20 Wendy 30

    解决办法是使用显式的拷贝构造函数,程序如下所示:

#include < iostream.h >
#include
<string .h >

struct  Node
{
    
char *name;
    
int age;
    Node(
char *n=""int a=0)
    
{
        name
=new char[strlen(n)+1];
        strcpy(name, n);
        age
=a;
    }

    Node(
const Node &n) //copy constructor
    {
        name
=new char[strlen(n.name)+1];
        strcpy(name, n.name);
        age
=n.age;
    }

}
;

void  main()
{
    Node node1(
"Roger"20)
    Node node2(node1);
//调用了显式的拷贝构造函数

    strcpy(node2.name, 
"Wendy");
    node2.age
=30;

    cout
<<node1.name<<' '<<node1.age<<' '
        
<<node2.name<<' '<<node2.age<<endl;
}


运行结果:
Roger 20 Wendy 30

 

3. 赋值运算符的重载
    

#include<iostream.h>
#include
<string.h>

struct Node
{
    
char *name;
    
int age;
    Node(
char *n=""int a=0)
    
{
        name
=new char[strlen(n)+1];
        strcpy(name, n);
        age
=a;
    }

    Node(
const Node &n) //copy constructor   
    {
        name
=new char[strlen(n.name)+1];
        strcpy(name, n.name);
        age
=n.age;
    }

    
    Node 
& operator=(const Node &n) //operator '=' overload
    {

           // 赋值操作符必须防止自身赋值
        
if(this!=&n)
        
{
            
if(name!=0)
                delete []name;
            name
=new char[strlen(n.name)+1];
            strcpy(name, n.name);
            age
=n.age;
        }

        
return *this;
    }

}
;

void main()
{
    Node node1(
"Roger"20);

    Node node2;
    
    node2
=node1; //调用重载的赋值运算符

    strcpy(node2.name, 
"Wendy");
    node2.age
=30;

    cout
<<node1.name<<' '<<node1.age<<' '
        
<<node2.name<<' '<<node2.age<<endl;
}
 


运行结果:
Roger 20 Wendy 30


转载于:https://my.oschina.net/u/139223/blog/64408

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值