用一个已经存在的对象创建新的对象,不会调用普通的构造函数,而是调用拷贝构造函数,如果类中没有定义拷贝构造函数,编译器将提供一个拷贝构造函数,它的功能是把已存在对象的成员变量赋值给新对象的成员变量。
用一个已存在的对象创建新的对象的语法:
类名 新对象名(已存在对象名);
类名 新对象名=已存在对象名;
#include<iostream>
using namespace std;
class CGirl
{
public:
string m_name;
int m_age;
//没有参数的普通构造函数。
CGirl(){
m_name.clear();
m_age = 0;
cout<<"调用了CGirl()构造函数。\n";
}
//析构函数
~CGirl(){cout<<"调用了~CGirl()\n";}
//超女自我介绍方法,显示姓名和年龄。
void show(){
cout<<"姓名:"<<m_name<<",年龄:"<<m_age<<endl;
}
};
int main(){
CGirl g1;
g1.m_name="钟哥";g1.m_age=18;
//类名 新对象名(已存在对象名);
//类名 新对象名=已存在对象名;
CGirl g2(g1);//CGirl g2=g1;
g2.show();
return 0;
}
调用了CGirl()构造函数。
//创建g1时候显示出来的,创建对象g2的时候没有显示日志,说明没有调用普通构造函数
姓名:钟哥,年龄:18//g2 show方法显示出来的日志,说明他的数据来源于对象g1
调用了~CGirl()
调用了~CGirl()
//最后g1 g2销毁的时候都调用了析构函数
--------------------------------
Process exited after 0.4833 seconds with return value 0
请按任意键继续. . .
然而如上是没有拷贝构造函数,编译器给你了一个拷贝构造函数;
拷贝函数的语法:
类名 (const 类名& 对象名{......}
注意:
1.访问权限必须是public。
2.函数名必须与类名相同,没有返回值,不写void。
3.如果类中定义了拷贝构造函数,编译器将不提供默认的拷贝构造函数。
#include<iostream>
using namespace std;
class CGirl
{
public:
string m_name;
int m_age;
//没有参数的普通构造函数。
CGirl(){
m_name.clear();
m_age = 0;
cout<<"调用了CGirl()构造函数。\n";
}
//没有重载的拷贝构造函数;
CGirl (const CGirl&gg){
//这里边一般只写变量初始化和拷贝相关的代码;
m_name="可爱的"+gg.m_name;
m_age=gg.m_age-1;
cout<<"调用了CGirl(const CGirl &gg)拷贝构造函数。\n";
}
//析构函数
~CGirl(){cout<<"调用了~CGirl()\n";}
//超女自我介绍方法,显示姓名和年龄。
void show(){
cout<<"姓名:"<<m_name<<",年龄:"<<m_age<<endl;
}
};
int main(){
CGirl g1;
g1.m_name="钟哥";g1.m_age=18;
//类名 新对象名(已存在对象名);
//类名 新对象名=已存在对象名;
CGirl g2(g1);
g2.show();
return 0;
}
调用了CGirl()构造函数。
调用了CGirl(const CGirl &gg)拷贝构造函数。
姓名:可爱的钟哥,年龄:17
调用了~CGirl()
调用了~CGirl()
--------------------------------
Process exited after 0.4759 seconds with return value 0
请按任意键继续. . .
注意:
4.以值传递的方式调用函数时,如果实参为对象,会调用拷贝构造函数。
#include<iostream>
using namespace std;
class CGirl
{
public:
string m_name;
int m_age;
//没有参数的普通构造函数。
CGirl(){
m_name.clear();
m_age = 0;
cout<<"调用了CGirl()构造函数。\n";
}
//没有重载的拷贝构造函数;
CGirl (const CGirl&gg){
//这里边一般只写变量初始化和拷贝相关的代码;
m_name="可爱的"+gg.m_name;
m_age=gg.m_age-1;
cout<<"调用了CGirl(const CGirl &gg)拷贝构造函数。\n";
}
//析构函数
~CGirl(){cout<<"调用了~CGirl()\n";}
//超女自我介绍方法,显示姓名和年龄。
void show(){
cout<<"姓名:"<<m_name<<",年龄:"<<m_age<<endl;
}
};
void func(CGirl g){
g.show();
}
int main(){
CGirl g1;
g1.m_name="钟哥";g1.m_age=18;
//类名 新对象名(已存在对象名);
//类名 新对象名=已存在对象名;
func(g1);
return 0;
}
调用了CGirl()构造函数。//创建对象g1的日志,调用了普通构造函数
调用了CGirl(const CGirl &gg)拷贝构造函数。
//调用函数的时候,创建形参对象g的日志,调用了拷贝构造函数。
姓名:可爱的钟哥,年龄:17
调用了~CGirl()//形参g销毁
调用了~CGirl()//对象g1销毁
--------------------------------
Process exited after 0.4765 seconds with return value 0
请按任意键继续. . .
5.函数以值的方式返回对象时,可能还会调用拷贝构造函数(vs会调用,linux不会bacause g++编译器做了优化)
6.拷贝构造函数可以重载,可以有默认参数。
类名(.....,const 类名&对象名,.......){.......}
#include<iostream>
using namespace std;
class CGirl
{
public:
string m_name;
int m_age;
//没有参数的普通构造函数。
CGirl(){
m_name.clear();
m_age = 0;
cout<<"调用了CGirl()构造函数。\n";
}
//没有重载的拷贝构造函数;
CGirl (const CGirl&gg,int ii){
//这里边一般只写变量初始化和拷贝相关的代码;
m_name="可爱的"+gg.m_name;
m_age=gg.m_age-ii;
cout<<"调用了CGirl(const CGirl &gg,int ii)拷贝构造函数。\n";
}
//析构函数
~CGirl(){cout<<"调用了~CGirl()\n";}
//超女自我介绍方法,显示姓名和年龄。
void show(){
cout<<"姓名:"<<m_name<<",年龄:"<<m_age<<endl;
}
};
void func(CGirl g){
g.show();
}
int main(){
CGirl g1;
g1.m_name="钟哥";g1.m_age=18;
//类名 新对象名(已存在对象名);
//类名 新对象名=已存在对象名;
CGirl g2(g1,5);
g2.show();
return 0;
}
调用了CGirl()构造函数。
调用了CGirl(const CGirl &gg,int ii)拷贝构造函数。
姓名:可爱的钟哥,年龄:13
调用了~CGirl()
调用了~CGirl()
--------------------------------
Process exited after 0.4754 seconds with return value 0
请按任意键继续. . .
7.如果类中重载了拷贝函数却没有定义默认的拷贝构造函数,编译器也会提供默认的拷贝构造函数。
#include<iostream>
using namespace std;
class CGirl
{
public:
string m_name;
int m_age;
//没有参数的普通构造函数。
CGirl(){
m_name.clear();
m_age = 0;
cout<<"调用了CGirl()构造函数。\n";
}
//没有重载的拷贝构造函数;
//CGirl (const CGirl&gg){
//这里边一般只写变量初始化和拷贝相关的代码;
// m_name="可爱的"+gg.m_name;
// m_age=gg.m_age-1;
// cout<<"调用了CGirl(const CGirl &gg)拷贝构造函数。\n";
//}
//有重载的拷贝构造函数;
CGirl (const CGirl&gg,int ii){
//这里边一般只写变量初始化和拷贝相关的代码;
m_name="可爱的"+gg.m_name;
m_age=gg.m_age-ii;
cout<<"调用了CGirl(const CGirl &gg,int ii)拷贝构造函数。\n";
}
//析构函数
~CGirl(){cout<<"调用了~CGirl()\n";}
//超女自我介绍方法,显示姓名和年龄。
void show(){
cout<<"姓名:"<<m_name<<",年龄:"<<m_age<<endl;
}
};
void func(CGirl g){
g.show();
}
int main(){
CGirl g1;
g1.m_name="钟哥";g1.m_age=18;
//类名 新对象名(已存在对象名);
//类名 新对象名=已存在对象名;
CGirl g2(g1);
g2.show();
return 0;
}
也不报错;