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 复习示例和静态类成员 不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存 如果在头文 ...
随机推荐
- 404 Note Found 队-Beta2
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- Mac OS X 命令行用户应当知道的八个终端工具
原文链接:Eight Terminal Utilities Every OS X Command Line User Should Know OS X 的Terminal 终端开辟了强大的UNIX实 ...
- sublime 一些常用功能和快捷键
Ctrl+D 选词 (反复按快捷键,即可继续向下同时选中下一个相同的文本进行同时编辑)Ctrl+G 跳转到相应的行Ctrl+J 合并行(已选择需要合并的多行时)Ctrl+L 选择整行(按住-继续选择下 ...
- BZOJ2595: [Wc2008]游览计划(斯坦纳树,状压DP)
Time Limit: 10 Sec Memory Limit: 256 MBSec Special JudgeSubmit: 2030 Solved: 986[Submit][Status][ ...
- NGS检测SNP
1,Fastq数据质控 2,Fastq转化成bam,包含头文件 bwa aln ref.fa test_1.fq > test_1.sai bwa aln ref.fa test_2.fq &g ...
- 4543: [POI2014]Hotel加强版
4543: [POI2014]Hotel加强版 链接 分析: f[u][i]表示子树u内,距离u为i的点的个数,g[u][i]表示在子树u内,已经选了两个深度一样的点,还需要在距离u为i的一个点作为第 ...
- CF833B The Bakery 线段树,DP
CF833B The Bakery LG传送门 线段树优化DP. 其实这是很久以前就应该做了的一道题,由于颓废一直咕在那里,其实还是挺不错的一道题. 先考虑\(O(n^2k)\)做法:设\(f[i][ ...
- cogs 421 [SDOI2009]HH的项链
主席树.比树状数组高端多了又好写. last[i]表示上一个颜色为i的数,没有则为0. 那么一个区间里的答案就显而易见了: \(\sum_{i=l}^r (last[i]<l)\) 上面的东西已 ...
- jmeter no-gui模式动态传递场景参数
jmeter进行性能压测时,有时候需要在linux上no-gui模式下运行,为了在no-gui模式下更方便的设置脚本的运行的场景, 将脚本的线程数,运行时间设置为动态参数,可以在脚本运行时动态设置“线 ...
- How to map Actions to a certain RibbonPage and RibbonGroup using the Application Model or in code
https://www.devexpress.com/Support/Center/Question/Details/S134617/how-to-map-actions-to-a-certain-r ...