文章目录
一,拷贝构造函数
常引用可以引用字面常量普通引用不可以
整个程序的运行创建了多少个对象?
#include<iostream>
using namespace std;
class Object
{
int value;
public:
//Object() { cout << "Object::Object" << this << endl; }
Object(int x ) :value(x) { cout << "Object::Object Create "<<this << endl; }
~Object() { cout << "Object::~Object " << this << endl; }
//拷贝构造函数(参数是当前类型的引用)
Object(Object& obj):value(obj.value)
//Object(Object obj) : value(obj.value)去掉引用形成死递归
{
cout << "Copy Create "<<this << endl;
}
void SetValue(int x) { value = x; }
int GetValue() const { return value; }
};
Object fun(Object obj)//3拷贝构造
{
//整个程序的运行创建了多少个对象
//
int val=obj.GetValue();
Object obja(val);//4
return obja;
}
int main()
{
Object objx(0);//1
Object objy(0);//2
//obja不能直接给objy赋值
//返回时构建一个副本临时变量称之为将亡值拷贝构造5
objy = fun(objx);
return 0;
}
因为是栈区所以先进后出,先4后3
尽量的减少对象的创建,不以引用返回
class Object
{
int value;
public:
//Object() { cout << "Object::Object" << this << endl; }
Object(int x ) :value(x) { cout << "Object::Object Create "<<this << endl; }
~Object() { cout << "Object::~Object " << this << endl; }
//写两个函数提高程序的通用性
int& Value() { return value;}
const int& Value()const { return value; }
//拷贝构造函数(参数是当前类型的引用)
Object(Object& obj):value(obj.value)
//Object(Object obj) : value(obj.value)去掉引用形成死递归
{
cout << "Copy Create "<<this << endl;
}
};
Object fun(const Object& obj)//
{
//整个程序的运行创建了多少个对象
//
int val = obj.Value();
Object obja(val);//3
return obja;
}
int main()
{
Object objx(0);//1
Object objy(0);//2
//obja不能直接给objy赋值将亡值的地址给了eax
//注意你将亡值对象构建在主函数之中(构建在调用者空间中)
//返回时构建一个副本临时变量称之为将亡值拷贝构造5
objy = fun(objx);//4
return 0;
}
以引用返回(不可取,除非返回的值生存期不受函数影响)
Object & fun(const Object& obj)//
{
//整个程序的运行创建了多少个对象
//
int val = obj.Value();
Object obja(val);//3
return obja;
}//已引用返回返回的是地址将obja的地址存于eax中当函数结束后空间被回收
int main()
{
Object objx(0);//1
Object objy(0);//2
//obja不能直接给objy赋值将亡值的地址给了eax
//返回时构建一个副本临时变量称之为将亡值拷贝构造5
objy = fun(objx);//4
return 0;
}
二,运算符的重载
类型名加括号给实参,调动其构造函数构造一个无名对象
Complex Add(const Complex& c)const//将亡值的地址在主函数空间中
Complex Add(const Complex& c)const将亡值在add的空间中
class Complex
{
private:
double Real,Image;
public:
Complex() :Real(0), Image(0) {}
Complex(double r, double i) :Real(r), Image(i)
{
cout << "Creat: " << this << endl;
}
Complex(const Complex& x) :Real(x.Real), Image(x.Image)
{
cout << "Copy Create: " << this << endl;
}
~Complex() { cout << "~Complex: " << this << endl; }
//Complex Add(const Complex*const this,const Complex& c)
Complex Add(const Complex& c)const//将亡值的地址在主函数空间中
//vs2019也不允许这样的存在
//Complex & Add(const Complex& c)const//将亡值在add的空间中
{
double r = this->Real + c.Real;
double i = this->Image + c.Image;
/*Complex tmp(r, i);//这样会多产生一个对象相比较下面
return tmp;*/
//类型名加括号给实参,调动其构造函数构造一个无名对象
return Complex(r, i);//此时的无名对象充当将亡值对象
//return Complex(this->Real+c.Real,this->Image+c.Image);
}
void Printf()
{
cout << "("<<Real << " + " << Image<<")" << endl;
}
};
int main()
{
Complex c1(1.2, 2.3);
Complex c2(4.5, 5.6);
Complex c3;
c3 = c1.Add(c2);//c3=Add(&c1,c2);
c3.Printf();
}
用运算符的重载
class Complex
{
private:
double Real,Image;
public:
Complex() :Real(0), Image(0) {}
Complex(double r, double i) :Real(r), Image(i)
{
cout << "Creat: " << this << endl;
}
Complex(const Complex& x) :Real(x.Real), Image(x.Image)
{
cout << "Copy Create: " << this << endl;
}
~Complex() { cout << "~Complex: " << this << endl; }
//Complex Add(const Complex*const this,const Complex& c)
//operator告诉我们的编译器+是一个合法的函数名
Complex operator+(const Complex& c)const//运算符的重载 //Complex Add(const Complex& c)const//将亡值的地址在主函数空间中
//vs2019也不允许这样的存在
//Complex & Add(const Complex& c)const//将亡值在add的空间中
{
double r = this->Real + c.Real;
double i = this->Image + c.Image;
/*Complex tmp(r, i);//这样会多产生一个对象相比较下面
return tmp;*/
//类型名加括号给实参,调动其构造函数构造一个无名对象
return Complex(r, i);//此时的无名对象充当将亡值对象
//return Complex(this->Real+c.Real,this->Image+c.Image);
}
void Printf()
{
cout << "("<<Real << " + " << Image<<")" << endl;
}
};
int main()
{
Complex c1(1.2, 2.3);
Complex c2(4.5, 5.6);
Complex c3;
//c3 = c1Add(c2);//c3=Add(&c1,c2);
c3 = c1 + c2;
//c3=c1.operator+(c2);c3=operator+(&c1,c2);
c3.Printf();
}
c++的六个缺省函数
class Object
{
public:
Object(){} 缺省构造函数
Object(){}缺省析构函数
Object(const Object & x){}缺省的拷贝构造函数
Object&operator=(const Object&x){return *this;}缺省的赋值语句
Object * operator&(){return this;}//普通对象的取地址符
const Object*operator&()const{return this;}//常对象的去地址符
}
普通的赋值语句和可以实现连=的赋值语句
class Object
{
private:
int value;
public:
//Object() { cout << "Object::Object" << this << endl; }
Object(int x) :value(x) { cout << "Object::Object Create " << this << endl; }
~Object() { cout << "Object::~Object " << this << endl; }
//void operator=(const Object& obj)//=运算符的重载赋值语句
//{
// this->value = obj.value;
//}//obja=objb=objc//因为void不可以进行连续赋值
/*obja=objb=objc相当于
obja=objb .operator=(objc);
obja=operator=(&objb,objc);
*/
//y要实现连等
Object & operator=(const Object& obj)
{
if (this != &obj)//防止自己给自己赋值
{
this->value = obj.value;
}
return *this;
}
//写两个函数提高程序的通用性
int& Value() { return value; }
const int& Value()const { return value; }
//拷贝构造函数(参数是当前类型的引用)
Object(Object& obj) :value(obj.value)
//Object(Object obj) : value(obj.value)去掉引用形成死递归
{
cout << "Copy Create " << this << endl;
}
};