student st={"zhangsan",false,28};
student str2 = st1; ===> student str2( st1 );
1、函数原型:student(const student &rhs)
2、作用:用一个已存在的对象,生成一个相同类型的新对象
3、系统给的默认的拷贝构造函数是一个浅拷贝, 有指针我们要考虑深拷贝(防止同一片内存被释放两次)
4、形参一定要用引用(防止形参对象递归构造)
原因:引用是不会生成新的对象,不用引用实际是形参传实参的过程,形参传实参实际是一个初始化的过程此时就会形成死循环
1、系统给的默认的赋值运算符重载函数是一个浅拷贝, 有指针我们要考虑深拷贝
2、作用:把一个已存在的对象,赋值给相同类型的已存在的对象
3、 函数实现:
(1)判断自赋值
(2)释放旧资源
(3)开辟新资源
(4)赋值
形参const
(1)防止实参被修改(2)接收隐式生成的临时量
4、返回值可以不用引用但是会生成一个对象 效率低(因为类的返回值都是由临时对象带出来的,除非引用,引用是直接返回的地址)
Student& operator=(const Student& rhs)
{
std::cout << this << " CGoods::operator=(const Student&)" << std::endl;
if (this != &rhs)
{
delete[] mname;
mname = new char[strlen(rhs.mname) + 1]();
strcpy(mname, rhs.mname);
msex = rhs.msex;
mage = rhs.mage;
}
return *this;
}
Student st1(“st1”,false,23);
st1 = 30; //查找是否带有一个整型参数的构造函数,若存在,则生成一个临时对象,在调用赋值运算符重载函数赋值给st1;
1.隐式生成临时对象 编译器推演需要的对象类型
2.显式生成临时对象 程序指明要生成的对象类型
优化:
如果临时对象生成的目的是为了生成新对像,以生成临时对象的方式来生成新对象。
生存周期:表达式结束。
引用会提升临时对象的生存周期,使临时对象变得和引用对象一样的生存周期,指针和引用不会生成新对象。
临时量
内置类型 ==》 常量
自定义类型 ==》 变量 内存
隐式生成 ==》 常量
类类型的返回值 :都是由临时对象带出来
class Test
{
public:
Test(int a, int b)
{
std::cout << this << "Test:: Test(int,int)" << std::endl;
ma = a;
mb = b;
}
Test(int a)
{
std::cout << this << "Test:: Test(int)" << std::endl;
ma = a;
}
Test()
{
std::cout << this << "Test:: Test()" << std::endl;
}
Test(const Test& rhs)
{
std::cout << this << "Test:: Test(const Test&)" << std::endl;
ma = rhs.ma;
mb = rhs.mb;
}
Test& operator=(const Test& rhs)
{
std::cout << this << "Test::operator = (const Test&)" << std::endl;
if (this != &rhs)
{
ma = rhs.ma;
mb = rhs.mb;
}
return *this;
}
~Test()
{
std::cout << this << "Test::~Test()" << std::endl;
}
int getValue()
{
return ma;
}
private:
int ma;
int mb;
};
Test gtest1(10, 20);//全局对象,调用带有两个参数的构造函数,生存周期:调用开始到程序结束。
int main()
{
Test test3;//局部对象,调用不带参数的构造函数,生存周期:调用开始到函数结束
Test test4(10, 20);//调用带有两个参数的构造函数,生存周期:调用开始到函数结束
Test test5 = test3;//调用拷贝构造函数
test5 = test4;//调用运算符重载函数
static Test test6(10, 20);//静态局部对象,调用带有两个参数的构造函数,存放在静态存储区,生存周期:整个程序运行期间
Test test7 = 10;//隐式生成,因为是生成一个新的对象,存在优化,不会生成临时量
Test test8 = Test(10);//显示生成,因为是生成一个新的对象,存在优化,不会生成临时量
test7 = 20;//隐式生成,会生成一个临时量,然后调用赋值运算符重载函数赋值给text7
test8 = Test(30);//显式生成,会生成一个临时量,然后调用赋值运算符重载函数赋值给text8
test8 = (Test)(10,10,10,20);//逗号运算符相当于--》(Test)(20);显式生成,会生成一个临时量,然后调用赋值运算符重载函数赋值给text8
Test* ptest9 = &Test(10, 20);//调用带有两个参数的构造函数,取地址赋给ptest9
Test& rtest10 = Test(10, 20);//引用不会生成新的对象,所以不会有临时量生成
const Test& rtest11 = 10;//隐式生成的
Test* ptest12 = new Test(10, 20);//动态生成,生存周期:调用开始到delete结束
Test* ptest13 = new Test[2];//动态生成一个数组,两个对象都要调用构造函数,生存周期:调用开始到delete结束
delete ptest12;
delete[] ptest13;
return 0;
}
Test test2(10, 20);//全局对象,调用带有两个参数的构造函数,生存周期:调用开始到程序结束。