36、经典问题三

什么时候需要重载赋值操作符?编译器是否提供默认的赋值操作符?

编译器为每个类默认重载了赋值操作符,默认的赋值操作符仅完成浅拷贝,当需要深拷贝时必须重载赋值操作符,赋值操作符与拷贝构造函数有相同的存在意义(浅拷贝与深拷贝)。 指代了外部资源需要深拷贝

#include <iostream>
#include <string>
using namespace std;
class Test
{
    int* m_pointer;
public:
    Test()
    {
        m_pointer = NULL;
    }
    Test(int i)
    {
        m_pointer = new int(i);
    }
    Test(const Test& obj)
    {

        m_pointer = new int(*obj.m_pointer);     // 申请内存,int类型的值。取的是参数对象pointer指针所指向的堆空间的

       }                                                                      //整形值,将整形值取出来并且复制到新申请的内存空间中去

 
    Test& operator = (const Test& obj)          //注意:返回应用,参数是const类型,不是自赋值,返回当前对象
    {
        if( this != &obj )
        {
            delete m_pointer;
            m_pointer = new int(*obj.m_pointer);
        }   
        return *this;
    }
    void print()
    {
        cout << "m_pointer = " << hex << m_pointer << endl;
    }
    ~Test()
    {
        delete m_pointer;
    }
};
int main()
{
    Test t1 = 1;
    Test t2;    
    t2 = t1;    
    t1.print();
    t2.print();    
    return 0;

}

完善数组类(无代码)。

重载赋值操作符,必然需要实现深拷贝。

二、如果一个类中什么都没有,编译器提供什么?

Test();        //默认构造函数

Test(const Test&) //拷贝构造函数

扫描二维码关注公众号,回复: 184917 查看本文章

Test& operator= (const Test&);  //重载赋值操作符

~Test();  //析构函数

关于string的疑问:

    string s="12345";

    const char*p=s.c_str();   //成员函数返回一个字符指针,这个字符指针代表c语言中的写法

    cout<<p<<endl;              //打印12345

    s.append(“abced”)   //末尾插入一个字符串,p成为了野指针

    cout,<<p<<endl;            //打印12345abced

错了,因为string对象内部维护了一个指向数据的char*指针( .c_str),这个指针可能在程序运行的过程中发生改变。当向尾部插入一个字符串时,指针发生了改变,重新申请堆空间,指向  新的堆空间, 旧的堆空间字符串内部将会释放掉,p指针指向释放的空间,成为野指针。

要抛弃c的编程思想。

#include <iostream>
#include <string>
using namespace std;
int main()
{
    const char* p = "12345";               // c语言的写法 *p
    string s = "" ;
    s.reserve(10);                               //改变大小为10个字节
    
    // 不要使用 C 语言中的方式操作 C++ 中的字符串
    for(int i=0; i<5; i++)
    {
        s[i] = p[i];

    }

if(!s.empty())

{

    cout << s << endl;

}

    return 0;
}

问题分析:c++写C语言的程序。for循环之前

string 内部维护(m_cstr, m_length=0)->10bytes

for循环之后:

 string(m_cstr,m_length=0)->12345+ ( 5bytes)        长度还为0;

改:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    const string p = "12345";              
    string s = "" ;
    s.reserve(10);                               //改变大小为10个字节
    s=p;

   cout << s << endl;

    return 0;

}

在需要进行深拷贝的时候必须重载赋值操作符,赋值操作符合拷贝构造函数 有同等重要的意义,string类通过一个数据空间保存字符数据。string类通过一个成员变量保存当前字符串的长度,c++开发避开C语言的思想。

猜你喜欢

转载自blog.csdn.net/ws857707645/article/details/80233171
36