<四>
#include <iostream>
#include <cstring>
class MyString {
public:
MyString(const char * _pname=nullptr) {
if (_pname == nullptr) {
pname = new char[1];
pname[0] = '\0';
}
else {
int len = strlen(_pname);
pname = new char[len + 1];
strcpy(pname, _pname);
}
std::cout << "构造函数= " <<(int *) this << std::endl;
}
MyString(const MyString & _val) {
int len = strlen(_val.pname);
pname = new char[len + 1];
strcpy(pname, _val.pname);
std::cout << "左值拷贝构造="<< (int *) this <<" 原目标="<<(int *)(&_val) << std::endl;
}
MyString & operator=(MyString & _val) {
delete[]pname;
pname = nullptr;
pname = new char[strlen(_val.pname)+1];
strcpy(pname, _val.pname);
std::cout << "左赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
MyString( MyString && _val) {
pname = _val.pname;
_val.pname = nullptr;
std::cout << "移动拷贝构造=" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
}
MyString & operator=(MyString && _val) {
delete[]pname;
pname = nullptr;
pname = _val.pname;
_val.pname = nullptr;
std::cout << "移动赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
~MyString() {
if (pname != nullptr) {
delete[] pname;
pname = nullptr;
}
std::cout << "析构函数="<<(int *)this << std::endl;
}
const char * getChar() { return pname; }
private:
char * pname;
};
MyString getStringA(MyString & ms) {
const char * p = ms.getChar();
int len = strlen(p);
char * newp = new char[len + 1];
MyString s(newp);
return s;
}
MyString getStringB(MyString & ms) {
const char * p = ms.getChar();
int len = strlen(p);
char * newp = new char[len + 1];
MyString *ps = new MyString (newp);
return *ps;
}
int main(int argc, char *argv[])
{
std::cout << "----------1---------" << std::endl;
MyString s1("1234");
std::cout << "----------2---------" << std::endl;
MyString s2=s1;
std::cout << "----------3---------" << std::endl;
MyString s3;
std::cout << "----------4---------" << std::endl;
s3 = getStringA(s1);
std::cout << "----------5---------" << std::endl;
MyString s4;
std::cout << "----------6---------" << std::endl;
s4 = getStringB(s1);
std::cout << "----------7---------" << std::endl;
}
/*
上面代码中
函数 MyString getStringA(MyString & ms)
方法中
MyString s(newp);
return s;
s 是一个具名对象(即是左值的),按理来说,这个函数返回的时候,将s对象要返回给main函数栈上的
匿名对象应该是匹配 左值拷贝构造函数,但结果是匹配了移动构造函数(右值拷贝构造)
函数 MyString getStringB(MyString & ms)
方法中 MyString *ps = new MyString (newp);
return *ps;
同样是返回对象给main函数栈中的匿名对象,使用的是左值拷贝构造
结合以上两个对比
如果类中同时存在 左值拷贝构造和移动构造函数,在函数中需要将局部栈对象返回给
main函数栈匿名对象构造对象时,由于局部栈对象在出函数作用域就销毁了,类似于匿名对象的
生命周期,所以哪怕对象是左值对象, 返回的时候为了性能考虑编译器会调用 移动构造函数
如上面代码中getStringA 函数中的 MyString s(newp); 完成了 return s 后,这个栈对象就
要销毁了,所以编译器为了性能,使用移动构造,直接使用这个对象的内存
但是如果函数对象中返回对象的生命周期不是随函数结束而销毁,那么就不能用移动的方式构造
main函数栈上的对象,因为移动构造的原理,就是指向原对象内存块,同时将原对象置0,置空, 这种方式
对于临时对象没问题,因为临时对象生命周期就在那一行,可以直接借用, 但是如果对象生命周期很长,后面
还可能需要用到原对象的话,那么就不能用移动构造方式构造对象,所以getStringB方法中的
MyString *ps = new MyString (newp);
return *ps;
匹配的任然是左值拷贝构造,ps指向的对象是堆上,意味着不会随着函数结束而自动销毁, 后面可能还会用这个
对象,所以不能用移动的方式构造main函数栈上的匿名对象,所以匹配的是左值构造函数
同时见下图
上面代码在关闭编译器优化情况下,运行结果如下
上面代码打开编译器优化情况下,运行结果如下
#include <iostream>
#include <cstring>
class MyString {
public:
MyString(const char * _pname=nullptr) {
if (_pname == nullptr) {
pname = new char[1];
pname[0] = '\0';
}
else {
int len = strlen(_pname);
pname = new char[len + 1];
strcpy(pname, _pname);
}
std::cout << "构造函数= " <<(int *) this << std::endl;
}
MyString(const MyString & _val) {
int len = strlen(_val.pname);
pname = new char[len + 1];
strcpy(pname, _val.pname);
std::cout << "左值拷贝构造="<< (int *) this <<" 原目标="<<(int *)(&_val) << std::endl;
}
MyString & operator=(MyString & _val) {
delete[]pname;
pname = nullptr;
pname = new char[strlen(_val.pname)+1];
strcpy(pname, _val.pname);
std::cout << "左赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
MyString( MyString && _val) {
pname = _val.pname;
_val.pname = nullptr;
std::cout << "移动拷贝构造=" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
}
MyString & operator=(MyString && _val) {
delete[]pname;
pname = nullptr;
pname = _val.pname;
_val.pname = nullptr;
std::cout << "移动赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
~MyString() {
if (pname != nullptr) {
delete[] pname;
pname = nullptr;
}
std::cout << "析构函数="<<(int *)this << std::endl;
}
const char * getChar() { return pname; }
private:
char * pname;
};
MyString getStringA(MyString & ms) {
const char * p = ms.getChar();
int len = strlen(p);
char * newp = new char[len + 1];
MyString s(newp);
return s;
}
MyString getStringB(MyString & ms) {
const char * p = ms.getChar();
int len = strlen(p);
char * newp = new char[len + 1];
MyString *ps = new MyString (newp);
return *ps;
}
int main(int argc, char *argv[])
{
std::cout << "----------1---------" << std::endl;
MyString s1("1234");
std::cout << "----------2---------" << std::endl;
MyString s2=s1;
std::cout << "----------3---------" << std::endl;
MyString s3= getStringA(s1);
std::cout << "----------4---------" << std::endl;
MyString s4= getStringB(s1);
std::cout << "----------5---------" << std::endl;
system("pause");
}
打开优化运行结果如下图
关闭优化运行结果如下图
#include <iostream>
#include <cstring>
class MyString {
public:
MyString(const char * _pname=nullptr) {
if (_pname == nullptr) {
pname = new char[1];
pname[0] = '\0';
}
else {
int len = strlen(_pname);
pname = new char[len + 1];
strcpy(pname, _pname);
}
std::cout << "构造函数= " <<(int *) this << std::endl;
}
MyString(const MyString & _val) {
int len = strlen(_val.pname);
pname = new char[len + 1];
strcpy(pname, _val.pname);
std::cout << "左值拷贝构造="<< (int *) this <<" 原目标="<<(int *)(&_val) << std::endl;
}
MyString & operator=(MyString & _val) {
delete[]pname;
pname = nullptr;
pname = new char[strlen(_val.pname)+1];
strcpy(pname, _val.pname);
std::cout << "左赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
MyString & operator=(MyString && _val) {
delete[]pname;
pname = nullptr;
pname = _val.pname;
_val.pname = nullptr;
std::cout << "右赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
~MyString() {
if (pname != nullptr) {
delete[] pname;
pname = nullptr;
}
std::cout << "析构函数="<<(int *)this << std::endl;
}
const char * getChar() { return pname; }
private:
char * pname;
};
MyString getString(MyString & ms) {
const char * p = ms.getChar();
int len = strlen(p);
char * newp = new char[len + 1];
MyString s(newp);
return s;
//return MyString(newp);
}
int main(int argc, char *argv[])
{
std::cout << "Hello world!" << std::endl;
MyString s1("1234");
MyString s2;
s2 = getString(s1);
system("pause");
}
#include <iostream>
#include <cstring>
class MyString {
public:
MyString(const char * _pname=nullptr) {
if (_pname == nullptr) {
pname = new char[1];
pname[0] = '\0';
}
else {
int len = strlen(_pname);
pname = new char[len + 1];
strcpy(pname, _pname);
}
std::cout << "构造函数= " <<(int *) this << std::endl;
}
MyString(const MyString & _val) {
int len = strlen(_val.pname);
pname = new char[len + 1];
strcpy(pname, _val.pname);
std::cout << "左值拷贝构造="<< (int *) this <<" 原目标="<<(int *)(&_val) << std::endl;
}
MyString & operator=(MyString & _val) {
delete[]pname;
pname = nullptr;
pname = new char[strlen(_val.pname)+1];
strcpy(pname, _val.pname);
std::cout << "左赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
MyString & operator=(MyString && _val) {
delete[]pname;
pname = nullptr;
pname = _val.pname;
_val.pname = nullptr;
std::cout << "右赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
~MyString() {
if (pname != nullptr) {
delete[] pname;
pname = nullptr;
}
std::cout << "析构函数="<<(int *)this << std::endl;
}
const char * getChar() { return pname; }
private:
char * pname;
};
MyString getString(MyString & ms) {
const char * p = ms.getChar();
int len = strlen(p);
char * newp = new char[len + 1];
return MyString(newp);
}
int main(int argc, char *argv[])
{
std::cout << "Hello world!" << std::endl;
MyString s1("1234");
MyString s2;
s2 = getString(s1);
system("pause");
}
上面没有右值拷贝构造函数
#include <iostream>
#include <cstring>
class MyString {
public:
MyString(const char * _pname=nullptr) {
if (_pname == nullptr) {
pname = new char[1];
pname[0] = '\0';
}
else {
int len = strlen(_pname);
pname = new char[len + 1];
strcpy(pname, _pname);
}
std::cout << "构造函数= " <<(int *) this << std::endl;
}
MyString(const MyString & _val) {
int len = strlen(_val.pname);
pname = new char[len + 1];
strcpy(pname, _val.pname);
std::cout << "左值拷贝构造="<< (int *) this <<" 原目标="<<(int *)(&_val) << std::endl;
}
MyString & operator=(MyString & _val) {
delete[]pname;
pname = nullptr;
pname = new char[strlen(_val.pname)+1];
strcpy(pname, _val.pname);
std::cout << "左赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
MyString( MyString && _val) {
pname = _val.pname;
_val.pname = nullptr;
std::cout << "右值拷贝构造=" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
}
MyString & operator=(MyString && _val) {
delete[]pname;
pname = nullptr;
pname = _val.pname;
_val.pname = nullptr;
std::cout << "右赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
~MyString() {
if (pname != nullptr) {
delete[] pname;
pname = nullptr;
}
std::cout << "析构函数="<<(int *)this << std::endl;
}
const char * getChar() { return pname; }
private:
char * pname;
};
MyString getString(MyString & ms) {
const char * p = ms.getChar();
int len = strlen(p);
char * newp = new char[len + 1];
return MyString(newp);
}
int main(int argc, char *argv[])
{
std::cout << "Hello world!" << std::endl;
MyString s1("1234");
MyString s2;
s2 = getString(s1);
system("pause");
}
#include <iostream>
#include <cstring>
class MyString {
public:
MyString(const char * _pname=nullptr) {
if (_pname == nullptr) {
pname = new char[1];
pname[0] = '\0';
}
else {
int len = strlen(_pname);
pname = new char[len + 1];
strcpy(pname, _pname);
}
std::cout << "构造函数= " <<(int *) this << std::endl;
}
MyString(const MyString & _val) {
int len = strlen(_val.pname);
pname = new char[len + 1];
strcpy(pname, _val.pname);
std::cout << "左值拷贝构造="<< (int *) this <<" 原目标="<<(int *)(&_val) << std::endl;
}
MyString & operator=(MyString & _val) {
delete[]pname;
pname = nullptr;
pname = new char[strlen(_val.pname)+1];
strcpy(pname, _val.pname);
std::cout << "左赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
MyString( MyString && _val) {
pname = _val.pname;
_val.pname = nullptr;
std::cout << "右值拷贝构造=" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
}
MyString & operator=(MyString && _val) {
delete[]pname;
pname = nullptr;
pname = _val.pname;
_val.pname = nullptr;
std::cout << "右赋值函数" << (int *) this << " 原目标=" << (int *)(&_val) << std::endl;
return *this;
}
~MyString() {
if (pname != nullptr) {
delete[] pname;
pname = nullptr;
}
std::cout << "析构函数="<<(int *)this << std::endl;
}
const char * getChar() { return pname; }
private:
char * pname;
};
MyString getString(MyString & ms) {
const char * p = ms.getChar();
int len = strlen(p);
char * newp = new char[len + 1];
return MyString(newp);
}
int main(int argc, char *argv[])
{
std::cout << "Hello world!" << std::endl;
MyString s1("1234");
MyString s3 = getString(s1);
system("pause");
}