什么时候需要重载赋值操作符?编译器是否提供默认的赋值操作符?
编译器为每个类默认重载了赋值操作符,默认的赋值操作符仅完成浅拷贝,当需要深拷贝时必须重载赋值操作符,赋值操作符与拷贝构造函数有相同的存在意义(浅拷贝与深拷贝)。 指代了外部资源需要深拷贝
#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&) //拷贝构造函数
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语言的思想。