<四>

#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");
}

posted @ 2023-01-05 14:48  Hello_Bugs  阅读(19)  评论(0编辑  收藏  举报