[初]定制类的基本复制行为

本文探讨了在C++中实现深拷贝与浅拷贝的重要性,通过具体实例介绍了如何定义复制构造函数和重载赋值运算符来管理类所分配的资源。

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

定义复制控制函数最为困难的部分通常在于认识到它们的必要性.

                                                                                             ---------<<C++Primer中文版(4)>>P441

 

分配内存或其他资源的类几乎总是需要定义复制控制成员来管理所分配的资源。如果一个类需要析构函数,则它几乎也总是需要定义复制构造函数和赋值操作符。

 

 

 

 

 

 

 

下面这个小程序使用自定义的String类,并显式的定义复制构造函数,重载赋值运算符,和给出析构函数以达到精确控制类的基本行为的目的。

1

String s = "hello";

String t;

String k = s;                  //调用了显式的复制构造函数

t = s;                              //调用显式的重载的赋值运算符

t[0] = 'j';                         

如果没有显示的提供这些行为的控制,当t[0]第一个字母被改动时,s的第一个字幕也将改变,因为他们共享”hello”在堆上的内存区域。这就是所谓的浅拷贝

显式的定义复制构造函数,重载赋值运算符能精确到达控制类的行为的目的,这里我们需要t的改变不影响到s,也就是所谓的深拷贝”.

2

还有一点要注意的是就是String k = s;时,这里的=号并不是被当重载的赋值运算符号,也就是说在定义类的新对象时候,= 不被当作是重载的赋值运算符。

只是调用了类的复制构造函数String(const & String);

 

#include <cstddef>

#include <iostream>

 

//参考资料<<CC++代码精粹>>20

 

using namespace std;

 

class String {

public:

    String() {

        count = 0;

        data="";

    };

String(const String&);                            //复制构造函数

String& String::operator=(const String& s);          //重载赋值运算符                          (这三者应该同时显式定义)

~String();                                                                              //析构函数

    String(const char*);        char& operator[] (size_t pos);

        friend ostream& operator<<(ostream&,const String&);

private:

    char* data;

    size_t count;

    void clone(const char*);

};

 

inline String::String(const char *s) {

    clone(s);

}

 

inline String::~String() {

    delete [] data;

}

 

inline char& String::operator[](size_t pos) {   //inline函数不写return也不会报错?(070406)

    return data[pos];

}

 

//显式的复制构造函数定义

String::String(const String& s) {

    clone(s.data);

}

 

//显示的赋值操作符重载

String& String::operator=(const String& s) {

    if (this!=&s) {

        delete[] data;

        clone(s.data);

    }

    return *this;

}

 

ostream& operator<<(ostream& os, const String& s) {

    os.write(s.data,s.count);

    return os;

}

 

void String::clone(const char*s) {

    count = strlen(s);

    data = new char[count+1];

    strcpy(data,s);

}

 

 

int main(int argc,int argv[]) {

    String s = "hello";

String t;

String k = s;                  //调用了显式的复制构造函数

t = s;                              //调用显式的重载的赋值运算符

    t[0] = 'j';                          //深拷贝

    cout << "S == " << s << endl;

    cout << "t == " << t << endl;

    return 0;

}

 

 

 

 

 

 

下面这个程序说明了在我们没有显式定义复制构造函数,赋值运算符时,编译器会为我们提供隐式的

#include <iostream>

#include <string>

#include <cstdio>

 

using namespace std;

 

class MemberA {

private:

    string name;

public:

    MemberA(string& _name) throw();

         ~MemberA() throw();

    //编译器在此添加隐藏的拷贝构造函数和赋值操作

};

 

MemberA::MemberA(string& _name) throw() {

    name = _name;        

    cout << "constructing " << name  << "!/n";

}

 

MemberA::~MemberA() throw() {

         cout << "deconstruct " << name  << "!/n";

}

 

class MemberB {

private:

    string name;

public:

    MemberB(string& _name) throw();

    ~MemberB() throw();

    MemberB(const MemberB&) throw();                             //覆盖默认拷贝操作

    MemberB& operator= (const MemberB&) throw();                 //覆盖默认赋值操作

};

 

MemberB::MemberB(string& _name) throw() {

    name = _name;        

    cout << "constructing " << name  << "!/n";

}

 

MemberB::MemberB(const MemberB& member) throw() {

    name = member.name;

    cout << "copying a Member/n";

}

 

MemberB::~MemberB() throw() {

         cout << "deconstruct " << name  << "!/n";

}

 

MemberB& MemberB::operator= (const MemberB&) throw(){

    cout << "assigning a Member/n";

    return *this;

}

 

int main() {

         {

        cout << "调用编译器提供的默认赋值操作的memberA ";

        string s1("A");

        string s2("B");

        string s3("C");

                   MemberA a(s1);

                   MemberA b(s2);

                   MemberA c(s3);

        c = a;

         }

 

    {

        cout << "调用编译器提供的默认拷贝操作的memberA";

        string s1("A");

        string s2("B");

        string s3("C");

                   MemberA a(s1);

                   MemberA b(s2);

                   MemberA c = a;

         }

 

         {

        cout << "调用自定义赋值操作(覆盖编译器默认赋值操作)的memberB ";

        string s1("A");

        string s2("B");

        string s3("C");

                   MemberB a(s1);

                   MemberB b(s2);

                   MemberB c(s3);

        c = a;

         }

 

    {

        cout << "调用自定义拷贝操作(覆盖编译器默认拷贝操作)memberB";

        string s1("A");

        string s2("B");

        string s3("C");

                   MemberB a(s1);

                   MemberB b(s2);

                   MemberB c = a;

         }

 

    system("pause");

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值