c++ 拷贝函数和赋值函数的区别

c++ 构造函数,拷贝构造函数,赋值函数,析构函数


1.构造函数

构造函数:: 当创建一个类的对象时,它被调用来对**类的数据成员进行初始化和内存分配**
对于c++的空类,编译器默认加入以下成员函数
1.默认构造函数
2.拷贝构造函数
3.析构函数
4.赋值函数(赋值运算符)

**************ATTENTION::***********
构造函数可以被重载(重载::函数名相同,参数不同)
析构函数只有一个,不能被重载,不带参数


2.拷贝构造函数

拷贝构造::一种特殊的构造函数,用基于同一类的一个对象构造和初始化另一个对象。
当没有拷贝构造函数时,通过默认拷贝构造函数来创建一个对象。
A a;
A b(a);
A b= a;
都是拷贝构造函数来创建对象b
*************ATTENTION******************
b 对象之前是不存在的,用a对象来构造和初始化b的!!!

何时调用拷贝构造函数
1. 对象以值传递的方式传入函数内
2. 对象以值传递的方式从函数返回
3. 对象需要通过另一个对象初始化

引入一个问题

#include <iostream>
using namespace std;
class Test {
    int i;
public:
    Test(int x) {
        i = x;
    }
    Test(const Test& a) {
        this->i = a.i;
        cout << "Copy" << endl;
    }
};
Test work() {
    Test tot(0);
    return tot;
}
/*Test work() {
    Test* tot = new Test(1);
    return *tot;
}*/
int main() {
    work();
    return 0;
}

该段代码— 对象以值传递的方式从函数返回
在debug版本下z——————能走到拷贝构造函数中
在release版本下z—————-不能走到拷贝构造函数

*****************************REASON*************************
copy elision 拷贝省略**,在这里也叫具名返回值优化(named return value optimization),详情厚度一下就行了。

VS的debug时一般不作该优化,所以会有拷贝;release时就会优化,没有拷贝,直接构造,原因自然是debug和release的编译优化配置不同。**

什么时候编译器生成默认的拷贝构造函数
1.用户未自定义,代码中却用到
2.用户定义构造函数,未定义拷贝构造函数,代码中用到

******************ATTENTION****************************
**系统默认提供的拷贝构造函数的工作方式是内存拷贝—浅拷贝。
如果对象中用到了需要手动释放的对象,就会出现问题,这时就需要手动重载拷贝构造函数—–实现深拷贝**

浅拷贝: 如果复制的对象中引用以一个外部内容(例如分配在堆上的数据),那么在复制这个对象的时候,让新旧对象指向同一个外部内容,就是浅拷贝。(指针虽然复制了,但所指向的空间内容并没有复制,而是由两个对象共用,两个对象不独立,删除弓箭存在问题)

深拷贝:如果在复制这个对象的时候为新对象制作了外部对象的独立复制,就是深拷贝。

拷贝构造函数重载声明 A(const A& other)

3.赋值函数

赋值函数:: 一个类的对象向该类的另一个对象赋值。

当没有重载赋值函数(赋值运算符)时,通过默认赋值函数来进行赋值操作。
A a;
A b;
b =a ;
********************ATTENTION***************************
a, b 对象是已经存在的,用a对象来赋值给b!!!!!!

赋值运算符的重载声明:
A& operator = (const A& other)

拷贝构造函数和赋值函数的区别

1.拷贝构造函数是一个对象初始化一块内存区域,这块内存就是新对象的内存去,而赋值函数是对于一个已经被初始化的对象进行赋值操作。

2。在数据成员包含指针对象的时候,一种是复制指针对象,另一种是引用指针对象。拷贝构造函数大多数是复制,赋值函数是引用对象。

3。实现不一样。拷贝–是构造函数,通过参数对象,初始化产生一个对象。赋值函数则把一个新的对象赋值给一个原有的对象——所有如果原有的对象中有内存分配要先把内存释放掉,而且还要检查一下两个对象是不是同一个对象,如果是,不做任何操作,直接返回

!!!!不想写拷贝构造和赋值函数,有不允许编译器自动生成,
最简单——将这两个函数声明为私有函数。

string 类的完成的3个函数实现

#include <string>
class string
{
    string(const char* str);
    string(const string& ohter);
    string& operator=(const string& other);
    ~string();
private:
    char* m_data;
};
// 构造函数
string::string(const char* str)
{
    if(str == NULL)
    {
        m_data = new char[1];
        m_data = '\n';
    }
    else
    {
        int strlen = strlen(str);
        m_data = new char[strlen + 1];
        strcpy(m_data, str);
    }
}
// 拷贝构造函数
string::string(const string& other)
{
    int strlen = strlen(other.m_data);
    m_data = new char[strlen +1];
    strcpy(m_data , other.m_data);
}
//赋值函数
string & string::operator=(const string& other)
{
    if(this == &other) //自我检查
    {
        return *this;
    }
    //删除原有数据内存
    delete []m_data;
    int strlen = strlen(other.m_data);
    m_data = new char[strlen +1];
    strcpy(m_data ,other.m_data);
    return 8this;
}
// 析构函数
string::~string()
{
    delete []m_data;
}

总结:: 对象不存在,且没用别的对象来初始化,调用构造函数
对象不存在,且用别的对象来初始化,调用拷贝构造
对象存在,用别的对象给他赋值,就是赋值函数

c++默认函数

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
拷贝构造函数是用来创建一个新对象并将其初始化为给定对象的副本的特殊成员函数。它通常用于以下情况: - 当一个对象通过值传递给函数或以值的形式返回时 - 当一个对象用另一个对象进行初始化时 - 当一个对象作为另一个对象的成员进行初始化时 对于类`Person`的拷贝构造函数,它会接受一个`const Person&`类型的参数,并将其成员变量`name_`赋值给新创建的对象的`name_`成员变量。 赋值运算符是用于将一个对象的值分配给另一个已经存在的对象的成员函数。它通常用于以下情况: - 当一个对象被另一个对象赋值时 - 当一个对象作为另一个对象的成员进行赋值时 对于类`Person`的赋值运算符,它会接受一个`const Person&`类型的参数,并将其成员变量`name_`赋值给当前对象的`name_`成员变量。然后,它将返回一个指向左侧运算对象的引用,以支持连续赋值的操作。 如果在类定义中没有显式定义拷贝构造函数赋值运算符,编译器会为类生成默认拷贝构造函数赋值运算符。此外,我们还可以使用`=default`来显式要求编译器生成合成的拷贝构造函数赋值运算符。这将使用默认的实现来完成拷贝赋值操作。 总之,拷贝构造函数用于创建一个对象的副本,而赋值运算符用于将一个对象的值赋给另一个已经存在的对象。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C++拷贝构造函数拷贝赋值运算符](https://blog.csdn.net/xiongya8888/article/details/89424224)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值