C++ 复制功能

简介:

C++ 复制功能

       说C++复制功能,它可能不是很熟悉。类中的拷贝构造函数和赋值操作符。可是其实或许我们一不小心就会忽略编译器所做的一些默认操作。引起晦涩的错误。以下分析几种场景:


一、场景一:所有默认

#include<stdio.h>
class base{
public:
	base(){}
	base(int dt):data(dt){}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};
class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};
int main()
{
	derived da(1,5);
	derived db(2,10);
	da.get();
	db.get();

	da = db;
	da.get();
	db.get();

	derived dc(da);
	dc.get();

	base ba(da);
	ba.get();
	getchar();
}
结果:


    假设在编译器中执行程序,我们知道,当调用复制函数是。除了派生类的成员被复制外。基类的成员也被复制。这是编译器的行为,当用户未定义复制行为时,编译器就会主动提供一个默认版本号同一时候在须要的时候悄悄的调用完毕复制工作。



场景二、基类默认,派生类自己定义

#include<stdio.h>
class base{
public:
	base(){}
	base(int dt):data(dt){}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};
class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	derived(const derived&d)
	{
		printf("call derived::copy construct function.\n");
		ddata = d.ddata;
	}
	derived& operator=(const derived&d)
	{
		printf("call derived::operator= function.\n");
		ddata = d.ddata;
		return *this;
	}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};
结果:


    从结果能够看出,当用户定义了复制函数时。一切默认行为就不会发生,即派生类中不会隐式调用基类的默认复制函数。


场景三、基类自己定义,派生类默认

#include<stdio.h>
class base{
public:
	base(){}
	base(int dt):data(dt){}
	base(const base&b)
	{
		printf("call base::copy construct function.\n");
		data = b.data;
	}
	base& operator=(const base&d)
	{
		printf("call base::operator= function.\n");
		data = d.data;
		return *this;
	}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};

class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};
结果:


    从结果能够看出。当派生类没有显示定义复制函数时,那么他就会调用默认的复制函数,而默认复制函数会自己主动调用基类的复制函数。


场景四、基类派生类都自己定义

#include<stdio.h>
class base{
public:
	base(){}
	base(int dt):data(dt){}
	base(const base&b)
	{
		printf("call base::copy construct function.\n");
		data = b.data;
	}
	base& operator=(const base&d)
	{
		printf("call base::operator= function.\n");
		data = d.data;
		return *this;
	}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};

class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	derived(const derived&d):base(d)
	{
		printf("call derived::copy construct function.\n");
		ddata = d.ddata;
	}
	derived& operator=(const derived&d)
	{
		printf("call derived::operator= function.\n");
		ddata = d.ddata;
		return *this;
	}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};

结果:


    从结果看出,仅仅要定义了派生类的复制函数,那么就不会隐式调用基类的复制函数。


结论:仅仅要派生类定义了复制函数,那么就不会隐式调用基类的复制函数,所以在这样的情况下。我们必须显示调用基类的复制函数,以免造成复制的不完整。

以下给出显示调用的样例:

class base{
public:
	base(){}
	base(int dt):data(dt){}
	base(const base&b)
	{
		printf("call base::copy construct function.\n");
		data = b.data;
	}
	base& operator=(const base&d)
	{
		printf("call base::operator= function.\n");
		data = d.data;
		return *this;
	}
	void get(){printf("base::data = %d\n",data);}
public:
	int data;
};

class derived:public base{
public:
	derived(){}
	derived(int dt,int ddt):base(dt),ddata(ddt){}
	derived(const derived&d):base(d)
	{
		printf("call derived::copy construct function.\n");
		ddata = d.ddata;
	}
	derived& operator=(const derived&d)
	{
		printf("call derived::operator= function.\n");
		base::operator=(d);
		ddata = d.ddata;
		return *this;
	}
	void get()
	{
		base::get();
		printf("derived::ddata = %d\n",ddata);
	}
private:
	int ddata;
};

结果:









本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5048433.html,如需转载请自行联系原作者


相关文章
|
设计模式 uml C++
C++中的装饰器模式:灵活地扩展功能
C++中的装饰器模式:灵活地扩展功能
318 0
|
编译器 C++
【C++】—— c++11新的类功能
【C++】—— c++11新的类功能
253 0
|
编译器 程序员 Linux
C++系列九:预处理功能
C++系列九:预处理功能
|
算法 C语言 C++
C++ std::chrono库使用指南 (实现C++ 获取日期,时间戳,计时等功能)(一)
C++ std::chrono库使用指南 (实现C++ 获取日期,时间戳,计时等功能)
6076 1
|
缓存 算法 安全
C++ std::chrono库使用指南 (实现C++ 获取日期,时间戳,计时等功能)(三)
C++ std::chrono库使用指南 (实现C++ 获取日期,时间戳,计时等功能)
850 1
|
安全 调度 C++
C++ std::chrono库使用指南 (实现C++ 获取日期,时间戳,计时等功能)(二)
C++ std::chrono库使用指南 (实现C++ 获取日期,时间戳,计时等功能)
1724 0
|
存储 C++ UED
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
1592 173
|
监控 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
346 0
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
518 5
|
算法 网络协议 数据挖掘
C++是一种功能强大的编程语言,
C++是一种功能强大的编程语言,
474 14