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 复习示例和静态类成员 不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存 如果在头文 ...
随机推荐
- CentOS 6.5环境下配置Arcgis Server 10.3
感觉arcgis server在Windows系统下过于消耗资源,现将其配置到linux下,仅用于学习用.文中安装截图较多.因水平有限,难免有不周之处,请指教. 一.安装前准备 配置linux环境:此 ...
- jQuery----奇偶选择器和索引选择器
奇偶选择器: $( " #uu>li:odd").css( " backgroundColor "," red " ); 获取id为u ...
- 利用canvas将网页元素生成图片并保存在本地
利用canvas将网页元素生成图片并保存在本地 首先引入三个文件: 1.<script type="text/javascript" src="js/html2ca ...
- [笔记] Delphi 10.2.1 Tokyo 安装使用笔记
Android 平台: ListView 滑动速度已有改善,但比起 Berlin 还是略慢一些(在较慢的机子可感觉的到)仅于 Android 平台,其它平台没差. TMemo, TEdit 输入文字的 ...
- 快速链接bioconductor,以及安装“XML”
options(useHTTPS=FALSE, BioC_mirror="http://bioconductor.org") source("http://biocond ...
- 关于SignalR连接数量问题的记录
在使用SignalR的项目测试时遇到了一个问题,开发环境用的是Win10的操作系统,在VS2017调试环境中运行项目,连接多个SignalR客户端是没有问题的,例如,三个用户在一个聊天室同时聊天.但是 ...
- JavaWeb基础—邮件发送
一.JavaMail概述与入门 JavaMail-java提供的一组API,用来收发邮件 中间有个邮件服务器: 客户端发给邮件服务器,另外一收件客户端从邮件服务器下载(最稳的还是163,QQ有点不靠谱 ...
- sklearn常见分类器的效果比较
sklearn 是 python 下的机器学习库. scikit-learn的目的是作为一个“黑盒”来工作,即使用户不了解实现也能产生很好的结果. 其功能非常强大,当然也有很多不足的地方,就比如说神经 ...
- ecCodes 学习 利用ecCodes Python API对GRIB文件进行读写
参考 https://www.ecmwf.int/assets/elearning/eccodes/eccodes2/story_html5.htmlhttps://confluence.ecmwf. ...
- Python学习之路:一天搞定基础部分
~代表省略的内容,如变量名.字符串等等 1.Pyhton中比较特别的运算: **:代表指数运算,例如2**3 = 8 //:代表整除运算,这一点和Java不同 2.Python的注释: #:单行注释 ...