C++:构造函数2——拷贝构造函数
前言:拷贝构造函数是C++中的重点之一,在这里对其知识进行一个简单的总结。
一、什么是拷贝构造函数
在C++中,对于内置类型的变量来说,在其创建的过程中用同类型的另一个变量来初始化它是完全可以的,如:
int value=;
int new_value=value;//在变量new_value创建的同时用同类型的变量value来初始化它
那么对于自定义的数据类型来说,是否可以在该类的一个对象创建时用该类的另一个对象对其进行初始化呢?看下例:
#include<iostream>
#include<string>
using namespace std;
class Student{
public:
Student()=default;//默认构造函数
Student(string name,int age):Name(name),Age(age){} //构造函数
~Student(){}//析构函数
void message();//打印对象的信息
private:
string Name;
int Age;
}; void Student::message(){
cout<<"My name is "<<Name<<endl;
cout<<"I am "<<Age<<" years old"<<endl;
}
int main(){
Student stu1("Tomwenxing",);
Student stu2(stu1);
stu2.message();
return ;
}

由上面的例子可以看出可以用一个类的对象去对该类的另一个正在创建的新对象进行初始化。而完成这个工作的就是类中的拷贝构造函数。所谓拷贝构造函数是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。如果编程者在编写自定义的类时没有自定义拷贝构造函数,那么编译器会在类中定义一个默认的拷贝构造函数。
语法:类名(const 类名 &对象名) { /*拷贝构造函数体*/}
#include<iostream>
#include<string>
using namespace std;
class Student{
public:
Student()=default;//默认构造函数
Student(string name,int age):Name(name),Age(age){} //构造函数
Student(const Student& stu){ //拷贝构造函数
Name=stu.Name;
Age=stu.Age;
cout<<"调用了拷贝构造函数!"<<endl;
}
~Student(){}//析构函数
void message();//打印对象的信息
private:
string Name;
int Age;
}; void Student::message(){
cout<<"My name is "<<Name<<endl;
cout<<"I am "<<Age<<" years old"<<endl;
}
int main(){
Student stu1("Tomwenxing",);
Student stu2(stu1);
stu2.message();
return ;
}

特别注意:
拷贝构造函数的函数名必须和类名相同,且其唯一的参数(对象的引用)是不可变的(const类型)
二、拷贝构造函数的调用
在C++中,有三种情况会使对象在创建时调用拷贝构造函数
case 1:对象以值传递的方式传入函数参数
当对象直接作为参数以值传递的方式传递给函数时,函数将调用类中的拷贝构造函数并将实参对象传递给该拷贝构造函数从而在内存中创建形参对象,该形参对象将在函数执行完毕后调用类的析构函数将其析构
#include<iostream>
#include<string>
using namespace std;
class Student{
public:
Student(){//默认构造函数
cout<<"调用了默认构造函数 "<<this<<endl;
}
Student(string name,int age):Name(name),Age(age){//构造函数1
cout<<"调用了构造函数1 "<<this<<endl;
}
Student(const Student& stu){
Name=stu.Name;
Age=stu.Age;
cout<<"调用了拷贝构造函数!"<<this<<endl;
}
~Student(){//析构函数
cout<<"调用了析构函数 "<<this<<endl;
}
void message();//打印对象的信息
private:
string Name;
int Age;
}; void Student::message(){
cout<<"My name is "<<Name<<endl;
cout<<"I am "<<Age<<" years old"<<endl;
} void func1(Student s){
cout<<"调用了函数func1"<<endl;
cout<<"形参变量的地址为"<<&s<<endl;
}
int main(){
Student stu("Tomwenxing",);
cout<<"实参变量的地址为"<<&stu<<endl;
cout<<"准备调用函数func1"<<endl;
func1(stu);
cout<<"函数func1调研完毕"<<endl;
return ;
}

case 2:对象以值传递的方式从函数返回
当对象以值传递的方式从函数返回时,函数会调用类中的拷贝构造函数并将要返回的对象传递给该拷贝构造函数从而在内存中创建一个临时对象,该临时对象会在返回后(不管有没有对象接收(拷贝)该临时对象)立马调用类中的析构函数进行析构。
#include<iostream>
#include<string>
using namespace std;
class Student {
public:
Student() {//默认构造函数
cout << "调用了默认构造函数 " << this << endl;
}
Student(string name, int age) :Name(name), Age(age) {//构造函数1
cout << "调用了构造函数1 " << this << endl;
}
Student(const Student& stu) {
Name = stu.Name;
Age = stu.Age;
cout << "调用了拷贝构造函数!" << this << endl;
}
~Student() {//析构函数
cout << "调用了析构函数 " << this << endl;
}
void message();//打印对象的信息
private:
string Name;
int Age;
}; void Student::message() {
cout << "My name is " << Name << endl;
cout << "I am " << Age << " years old" << endl;
} Student func1() {
cout << "调用了函数func1" << endl;
Student s("Tomwenxing", );
cout << "函数中的局部对象s在内存中的地址:" << &s << endl;
return s;
}
int main() {
cout << "准备调用函数func1" << endl;
func1();
cout << "函数func1调研完毕" << endl;
return ;
}

case 3:对象在创建过程中被相同类型的其他对象初始化
当对象在创建过程中被同类型的其他对象进行初始化时,该对象会调用类中的拷贝构造函数并将对其初始化的对象作为实参传递给该类的拷贝构造函数,从而最终将本对象成功创建
#include<iostream>
#include<string>
using namespace std;
class Student{
public:
Student(){//默认构造函数
cout<<"调用了默认构造函数 "<<this<<endl;
}
Student(string name,int age):Name(name),Age(age){//构造函数1
cout<<"调用了构造函数1 "<<this<<endl;
}
Student(const Student& stu){
Name=stu.Name;
Age=stu.Age;
cout<<"调用了拷贝构造函数!"<<this<<endl;
}
~Student(){//析构函数
cout<<"调用了析构函数 "<<this<<endl;
}
void message();//打印对象的信息
private:
string Name;
int Age;
}; void Student::message(){
cout<<"My name is "<<Name<<endl;
cout<<"I am "<<Age<<" years old"<<endl;
} int main(){
Student stu1("Tomwenxing",);
Student stu2(stu1);//初始化形式一
Student stu3=stu1;//初始化形式二
return ;
}

C++:构造函数2——拷贝构造函数的更多相关文章
- 类string的构造函数、拷贝构造函数和析构函数
		原文:http://www.cnblogs.com/Laokong-ServiceStation/archive/2011/04/19/2020402.html 类string的构造函数.拷贝构造 ... 
- c++ 构造函数,拷贝构造函数,析构函数与赋值操作符
		题目: 为下面的Rectangle类实现构造函数,拷贝构造函数,赋值操作符,析构函数. class Shape { int no; }; class Point { int x; int y; }; ... 
- C++中的构造函数,拷贝构造函数和赋值运算
		关于C++中的构造函数,拷贝构造函数和赋值运算,以前看过一篇<高质量C++/C编程指南>的文章中介绍的很清楚,网上能搜索到,如果想详细了解这方面的知识可以参看一下这篇文章. 常见的给对象赋 ... 
- 编写类String的构造函数、拷贝构造函数、析构函数和赋值函数
		一.题目: class String { public: String(const char *str = NULL); // 普通构造函数 String(const String &othe ... 
- CPP_类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数
		类默认函数:构造函数,拷贝构造函数,赋值函数和析构函数 // person.h #ifndef _PERSON_H_ #define _PERSON_H_ class Person{ public : ... 
- C++中构造函数,拷贝构造函数和赋值函数的区别和实现
		C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法.下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象 ... 
- C++中的构造函数,拷贝构造函数,赋值函数
		C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法.下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象 ... 
- C++ 构造函数_拷贝构造函数
		拷贝构造函数 
- C++构造函数和拷贝构造函数详解
		构造函数.析构函数与赋值函数是每个类最基本的函数.它们太普通以致让人容易麻痹大意,其实这些貌似简单的函数就象没有顶盖的下水道那样危险. 每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含 ... 
- C++ 构造函数、拷贝构造函数、赋值运算符
		<C++ Primer Plus> 12.1 动态内存和类 12.1.1 复习示例和静态类成员 不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存 如果在头文 ... 
随机推荐
- Angular动态表单生成(六)
			动态表单之根据Json生成表单 我们在实际的使用中,动态表单往往是由服务器端的一系列配置,然后返回数据给客户端,最后客户端根据数据来动态的生成表单.那么怎么像我们上面所描述的这样,生成一个可以让我们的 ... 
- 使用XWAF框架(2)——上传文件
			XWAF提供了上传文件的HttpFileUploader工具类,具备强大的多文件上传.文件类型过滤.文件大小限制.存储目录设置.文件名称更改等功能,简化了Web应用开发的编程工作. 它能同时解析表单参 ... 
- linux下使用shell脚本获取终端宽度
			获取终端大小时候的学习 学习日期:2018/11/3 问题来源: 在写shell脚本时想输出一行占满整个终端屏幕宽度的 横杠 发现for循环会导致执行缓慢 解决方法: 使用yes 命令 sed '50 ... 
- nginx如何做到TCP的负载均衡
			原文:https://blog.csdn.net/u011218159/article/details/50966861 TCP 的 负载均衡 这个片段描述了如何通过nginx plus进行负 ... 
- fixed fluid layout
			<div id="fixed">Sidebar</div> <div id="fluid">Content</div& ... 
- SpringIDE的安装
			要安装SpringIDE,需要先知道当前eclipse的版本,打开Eclipse,Help -> About Eclipse 然后去 http://spring.io/tools/sts/all ... 
- 【转载】COM  组件设计与应用(十五)——连接点(vc6.0)
			原文:http://vckbase.com/index.php/wv/1256.html 一.前言 上回书介绍了回调接口,在此基础上,我们理解连接点就容易多了. 二.原理 图一.连接点组件原理图.左侧 ... 
- 柯朗微积分与数学分析习题选解(1.2 节 d)
			一直在读<陶哲轩实分析>,陶的书非常的严谨,环环相扣,但是也有个缺点就是计算性的例子和应用方面的例子太少了.所以就又找了本柯朗的<微积分与数学分析>搭配着看.柯朗的书的习题与陶 ... 
- 基于socketserver实现并发
			基于tcp的套接字,关键就是两个循环,一个链接循环,一个通信循环 socketserver模块中分两大类:server类(解决链接问题)和request类(解决通信问题) 一.分析socketserv ... 
- SSISDB2:SSIS工程的操作实例
			SSISDB 系列随笔汇总: SSISDB1:使用SSISDB管理Package SSISDB2:SSIS工程的操作实例 SSISDB3:Package的执行实例 SSISDB4:当前正在运行的Pac ... 
