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 复习示例和静态类成员 不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存 如果在头文 ...
随机推荐
- Yii2 查询条件
Model::find() 字符串格式,例如:'status=1' 哈希格式,例如: ['status' => 1, 'type' => 2] 操作符格式,例如:['like', 'nam ...
- pandas对excel处理过程中的总结
在处理excel数据时需要将一组具有相同标签值的数据给按标签抽取出来,同样的标签值对应着同一个类别,这项操作让我对pandas的聚合功能有了更深刻的认识. 所谓聚合groupby,实际上是指将向量或者 ...
- WPF设置全局字体和字体嵌入
原文:WPF设置全局字体和字体嵌入 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/CLeopard/article/details/40590373 ...
- Gson转换复杂对象报错【类型强转错误】
一.问题: 项目里遇到一个需求,规则文件下载后,导入本地解析. 采用的方案是:获取复杂对象,使用谷歌Gson转换为字串保存为文件下载,客户端读取文件,解析字串,反解对象 遇到的问题:传输的对象是一个嵌 ...
- 【转载】C++创建对象的两种方法
原文:http://blog.sina.com.cn/s/blog_586b6c050100dhjg.html 在C++里,有两种方法创建对象: 方法一: ClassName object(param ...
- 13-[CSS]-postion位置:相relative,绝absolute,固fixed,static(默认),z-index
1.postion位置属性 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- spark-sql用hive表格,在spark-submit运行jar包时遇到的问题
1.编程时无法加载hive包,需要在编译好的spark(用spark-shell启动,用spark-sql能够直接访问hive表)的lib目录下,考出assembly包,为其创建一个maven的rep ...
- 单元测试 java调用不同包下的类时,出现 NoClassDefFoundError 的解决方案
网上查了下,原因很多: https://blog.csdn.net/u013065023/article/details/71171373 不过只需要在做单元测试时把相应的类放到单元测试所在类的同包下 ...
- pycharm如何回到过去某个时间
在编写代码是,我们可能会写错代码,或者是误删某个文件,那么问题来了,如何回到过去的某个时间段,来弥补我们犯下的错呢? 1.如果是恢复删除的文件则右击之前文件所在的文件夹 2.右击文件夹的显示效果如图 ...
- python之GIL(Global Interpreter Lock)
一 介绍 ''' 定义: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple nati ...