1:当函数以相应的类作为形参列表时,对象可以作为函数的参数传入。在学习函数时,我们曾提过,值传递先复制实参产生副本。那么对象的副本是怎样的呢?

复制构造函数是指类的对象被复制时所调用的函数。下面两种情况中对象都会调用复制构造函数。

(1)将一个对象赋值给另外一个对象时。例如:

对象1=对象2;

对象1(对象2);

上面的程序中对象2的复制构造函数会被调用。

(2)作为值传递的实参。例如:

function(对象1);

在function函数体内,使用的是对象1的副本。所以之前会调用对象1的复制构造函数。

和构造函数一样,C++在未发现自定义的复制构造函数之前会创建一个默认的构造函数。

自定义的复制构造函数的声明格式为:

类名(类名& 形参)

值得注意的是,复制构造函数时引用传递的函数。既然默认复制构造函数已经完成复制工作,那为何需要重新定义它呢?例如,一个类具有指针类型的数据,默认复制构造函数执行之后,原对象和副本的指针成员指向的是同一个内存空间。通过指针改变该内存,就会改变两个对象实际应用的数据(也就是这块内存的内容)。这时可以自定义复制构造函数,将两个指针的内存分离开。

2:代码如下:

(1)germ.h

#include <string>
using std::string;
class germ{
public:
int m_age;
string m_name;
germ(germ& g);//自定义复制构造函数 类名(类名&形参)
germ(string s);//构造函数
~germ();//析构函数,执行收尾工作
};

(2)germ.cpp

#include "stdafx.h"
#include "germ.h"
#include <iostream>
using std::cout;
using std::endl;
germ::germ(string s)
{
m_name = s;
m_age = ;
cout<<"发现了"<<m_name<<endl;
}
germ::germ(germ& g)
{
g.m_age +=;
this->m_age = ;
this->m_name =g.m_name + "的复制体";
cout<<"产生了"<<g.m_name<<"的复制体"<<endl;
}
germ::~germ(){
cout<<this->m_name<<"被消灭了"<<endl;
}

(3)main.cpp

// 7.7.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream>
#include "germ.h"
using std::cout;
using std::endl;
germ copyGerm(germ gc)
{
return gc;
}
int main()
{
germ g1("有氧菌");//(发现了有氧菌)
germ g2(g1);//第一个germ的意思是声明一个对象g2,g2(g1)的意思是将g1赋值给g2,此时将会调用复制构造函数(产生了有氧菌的复制体)
germ g3("无氧菌");//(发现了无氧菌)
germ g4 = g3;//意思同样是将g3赋值给g4,此时将会调用复制构造函数。(产生了无氧菌的复制体)
germ g5 = copyGerm(g4);//此时也调用复制构造函数了,只要有副本,就会调用复制构造函数。此处调用了两次,copygerm()一次,等号一次(产生了无氧菌复制体的复制体,产生了无氧菌复制体的复制体的复制体)
return ;
}
//注意,调用copygerm后,copygerm会立即被释放,所以会立即放出析构函数,输出(无氧菌的复制体的复制体被消灭了)
//以后依次g5,g4,g3,g2,g1被释放,故依次被输出这些被消灭

运行结果:

从程序运行结果来分析代码:首先在主函数中产生了g1对象,由复制构造函数产生了g1的复制体g2——有氧菌复制体。之后定义了g3——无氧菌。通过复制构造函数产生了g3的复制体g4。前四行输出即是上面所述的过程。g5的产生前,g5所在赋值语句等号右边的copyGerm函数被调用,传递的实参为g4——无氧菌的复制体。如同开始提到的,值传递实参对象产生副本,副本就是形参gc——无氧菌复制品的复制品。函数执行完毕后,传递回临时变量,内容是gc。g5的值经过复制语句,所以它是gc(临时变量使用的内存)的复制品。

C++入门经典-例7.7-对象与复制,菌类的繁殖的更多相关文章

  1. C++入门经典-例7.8-const对象,标准尺寸

    1:当建立一个对象之后,如果不希望它的任何数据发生改变,可以将其直接声明为const对象,例如: const 类名 对象名 const对象必须初始化.我们可以调用它的数据和函数,但是不可以对他们进行修 ...

  2. C++入门经典-例6.6-字符串复制

    1:字符串复制函数strcpy的格式如下: strcpy(字符数组名,字符串) 其作用是把字符串中的字符串复制到字符数组中.需要注意的是,字符串结束标志'\0'也一同被复制. 注意是将后面的内容复制给 ...

  3. 《挑战30天C++入门极限》C++类对象的复制-拷贝构造函数

        C++类对象的复制-拷贝构造函数 在学习这一章内容前我们已经学习过了类的构造函数和析构函数的相关知识,对于普通类型的对象来说,他们之间的复制是很简单的,例如: int a = 10; int ...

  4. C++入门经典-例7.6-this指针,同一个类的不同对象数据

    1:对于类的非静态成员,每个对象都有自己的一份拷贝,即每个对象都有自己的数据成员,不过成员函数却是每个对象共享的.那么调用共享的成员函数如何找到自己的数据成员呢?答案是通过类中隐藏的this指针. 2 ...

  5. C++入门经典-例7.10-运算符的重载,重载加号运算符

    1:曾经介绍过string类型的数据,它是C++标准模版库提供的一个类.string类支持使用加号“+”连接两个string对象.但是使用两个string对象相减确实非法的,其中的原理就是C++所提供 ...

  6. C++入门经典-例9.3-类模板,简单类模板

    1:使用template关键字不但可以定义函数模板,而且可以定义类模板.类模板代表一族类,它是用来描述通用数据类型或处理方法的机制,它使类中的一些数据成员和成员函数的参数或返回值可以取任意数据类型.类 ...

  7. C++入门经典-例8.10-实现抽象类中的成员函数

    1:抽象类通常作为其他类的父类,如果从抽象类派生的子类是抽象类,则子类必须实现父类中的所有纯虚函数.代码如下: // 8.10.cpp : 定义控制台应用程序的入口点. // #include &qu ...

  8. C++入门经典-例8.9-抽象类,纯虚函数,创建纯虚函数

    1:包含有纯虚函数的类称为抽象类,一个抽象类至少具有一个纯虚函数.抽象类只能作为基类派生出的新的子类,而不能在程序中被实例化(即不能说明抽象类的对象),但是可以使用指向抽象类的指针.在程序开发过程中并 ...

  9. C++入门经典-例8.8-虚继承

    1:以前讲到从CBird类和CFish类派生子类CWaterBird时,在CWaterBird类中将存在两个CAnimal类的复制.那么如何在派生CWaterBird类时使其只存在一个CAnimal基 ...

随机推荐

  1. CSS总结六:动画(一)ransition:过渡、animation:动画、贝塞尔曲线、step值的应用

    transition-property transition-duration transition-timing-function transition-delay animation-name a ...

  2. openlayers 地图移动缩放动画

    map.getView().animate({ // 只设置需要的属性即可 center: [data.jd, data.wd], // 中心点 zoom: 11, // 级别 rotation: u ...

  3. 使用脚本启动fabric时出错

    Error: got unexpected status: BAD_REQUEST -- error authorizing update: error validating ReadSet: rea ...

  4. 鼠标悬停设置layui tips提示框

    官方介绍:吸附层,灵活判断出现的位置,默认在元素的右侧弹出. layer.tips(content, follow, options) layer.tips(msg, '#id',{tips: 1}) ...

  5. DA_05_Linux(CentOS6.7) 安装MySql5.7数据库

    1系统约定 安装文件下载目录:/data/software Mysql目录安装位置:/usr/local/mysql 数据库保存位置:/data/mysql 日志保存位置:/data/log/mysq ...

  6. 2.LVS的三种工作模式_NAT模式

    1.LVS的三种工作模式 1)VS/NAT模式(Network address translation) 2)VS/TUN模式(tunneling) 3)DR模式(Direct routing) 1. ...

  7. [ZOJ 4025] King of Karaoke

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5766 求两个序列的相对元素的差出现次数最多的,最低出现一次. AC代 ...

  8. 牛客小白月赛12 D 月月给华华出题 (欧拉函数,数论,线筛)

    链接:https://ac.nowcoder.com/acm/contest/392/D 来源:牛客网 月月给华华出题 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 131072K, ...

  9. zencart设置特价商品价格

    登录后台-工具-安装SQL脚本(Install SQL Patches) 运行以下语句: , '0001-01-01'); 红色部分请替换成实际要设置的数据:1234表示产品ID,888表示特价.

  10. 帝都之行5day:还是工作上的事

    前两天开始面试找工作,周一整好简历,学历不行也没办法,但还是如实写了,自己看了一下,觉得还凑合,毕竟还是有几年经验的,就开始投了 选了十来个智联推荐的企业,然后把简历设为公开,开始等消息吧…… 投递成 ...