1什么时候需要重载赋值操作符?编译器是否提供默认的赋值操作符?
编译器为每个类默认重载了赋值操作符,默认的赋值操作符仅完成浅拷贝,当需要深拷贝时必须重载赋值操作符,赋值操作符与拷贝构造函数有相同的存在意义(浅拷贝与深拷贝)。 指代了外部资源需要深拷贝
#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;
}
研究main中的功能,当t2=t1时,浅拷贝,析构函数析构了两次同样的堆空间,释放两次。
完善数组类(无代码)。
重载赋值操作符,必然需要实现深拷贝。
如果一个类中什么都没有,编译器提供什么?
Test(); //默认构造函数
Test(const Test&) //拷贝构造函数
Test& operator= (const Test&); //重载赋值操作符
~Test(); //析构函数
2关于string的疑问:下面代码输出什么?
string s="12345";
const char*p=s.c_str(); //成员函数返回一个字符指针,这个字符指针代表c语言中的写法(只有这条是c的)
cout<<p<<endl; //打印12345
s.append(“abced”) //末尾插入一个字符串,p成为了野指针
cout<<p<<endl; //打印12345,而不是12345abced
改为:
string s="12345";
const char* p=s.c_str();
cout<<s<<endl;
s.append(“abced”)
cout<<s<<endl;
//结果是12345 12345abced原因:因为string对象内部维护了一个指向数据的char*指针( .c_str),这个指针可能在程序运行的过程中发生改变。当向尾部插入一个字符串时,指针发生了改变,重新申请堆空间,指向新的堆空间,而p指向之前的地址,旧的堆空间字符串内部将会释放掉,p指针指向释放的空间,成为野指针。
要抛弃c的编程思想。
3:
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 s 内部维护(m_cstr, m_length=0)->10bytes
for循环之后:
string 内部维护(m_cstr,m_length=0)->12345+ ( 5bytes) 长度还为0;
改:
const string p = "12345";
string s = "" ;
s.reserve(10); //改变大小为10个字节
s=p;
cout << s << endl;
return 0;在需要进行深拷贝的时候必须重载赋值操作符,赋值操作符合拷贝构造函数 有同等重要的意义,string类通过一个数据空间保存字符数据。string类通过一个成员变量保存当前字符串的长度,c++开发避开C语言的思想。
深拷贝与赋值操作符
本文探讨了在C++中何时需要重载赋值操作符以实现深拷贝,解释了深拷贝与浅拷贝的区别,并通过具体代码示例展示了如何正确地实现赋值操作符。同时,文章还讨论了std::string类的行为及其潜在陷阱。
2197





