代码1
#include <iostream>
#include <functional>
#include<cstdio>
#include<cstring>
using namespace std;
class MyString3 {
public:
MyString3(const char * pChar=nullptr) {
if (pChar == nullptr) {
this->pString = new char[1];
this->pString[0] = '\0';
}
else {
int len = strlen(pChar);
this->pString = new char[len + 1];
strcpy(this->pString, pChar);
}
cout << "MyString 构造函数 函数地址"<<(int *)this << endl;
}
// 左值拷贝构造
MyString3(const MyString3 & _rval) {
int len = strlen(_rval.pString);
this->pString = new char[len + 1];
strcpy(this->pString, _rval.pString);
cout << "MyString 左值拷贝构造函数,原对象地址"<<(int *)(&_rval) <<"目标对象地址"<<(int *)(this) << endl;
}
//左值赋值重载函数
MyString3 & operator =(const MyString3 & _rval) {
cout << "MyString 左值赋值重载函数,原对象地址"<<(int *)(&_rval) <<"目标对象地址"<<(int *)(this) << endl;
if (this == &_rval) { return *this; }
else {
delete[]this->pString;
this->pString = nullptr;
int len = strlen(_rval.pString);
char *tep = new char[len + 1];
strcpy(tep,_rval.pString);
this->pString = tep;
return *this;
}
}
const char * c_str() {
return pString;
}
~MyString3() {
cout << "MyString 析构函数,析构函数对象地址"<<(int *)(this) << endl;
delete[] this->pString;
pString = nullptr;
}
private:
char *pString;
};
MyString3 getMyString(MyString3 & ms) {
const char * tep = ms.c_str();
MyString3 S(tep);
return S;
}
int main() {
MyString3 S1("ABCDEF123456");
MyString3 S2;
S2=getMyString(S1);
std::cout<<"S2对象地址"<<(int *)(&S2)<<std::endl;
system("pause");
return 0;
}
上面出现大量重复的空间开辟和析构过程.
如何解决上面的问题?
先回顾一下以前关于左值引用,和右值引用
int a =10;
int & ra=a;
左值,有名字,有地址 如a ,可以将左值引用绑定到一个左值上
int &b =100;//错误 不能将左值引用绑定到一个右值,100是右值
右值:没有名字,没有地址
int &&rb=100;//ok 将右值引用绑定到 右值
int &&rb=a;//错误,不能将右值引用绑定到左值
int &b =100 //错误, 如果要想可以 需要 const int &b =100; 编译器其实生成了一个 临时量 int tep=100; int &b=tep;
同理
// 不可以,因为C++编译器将匿名对象都看做右值,所以要 MyString3 && rs=MyString3;或者 const MyString3 &s=MyString3;
MyString3 &s=MyString3("ABC");
对于 C++编译器将匿名对象都看做右值,MyString3 &s=MyString3("ABC");
不同的编译器做法不一样,gcc编译器不允许,但是MSVC上可以 如下两张图
代码2
#include <iostream>
#include <functional>
#include<cstdio>
#include<cstring>
using namespace std;
class MyString3 {
public:
MyString3(const char * pChar=nullptr) {
if (pChar == nullptr) {
this->pString = new char[1];
this->pString[0] = '\0';
}
else {
int len = strlen(pChar);
this->pString = new char[len + 1];
strcpy(this->pString, pChar);
}
cout << "MyString 构造函数,对象地址"<<(int *)(this) << endl;
}
// 左值拷贝构造
MyString3(const MyString3 & _rval) {
int len = strlen(_rval.pString);
this->pString = new char[len + 1];
strcpy(this->pString, _rval.pString);
cout << "MyString 左值拷贝构造函数,原对象地址"<<(int *)(&_r