一张图看懂MingW GCC 5.2.0中的C++的的拷贝构造函数

要了解copy构造函数使用原理,最好是用完整的代码测试一下,看看它是怎么工作,在什么 情况下会被调用,什么 情况下不会被调用,百度了一些名师讲座,在这里讲的也是乱七八糟,与我在实验环境中,实验结果,也不相同。在GCC只有在用一个类对象对另一个同类对象初始化时,才会发生copy构造调用,这包含在函数参数中调用(值传递,实参赋值给形参)。

在VS中的copy构造函数可能会有些不同,没有测试。。


本文例子在MingW GCC 5.2.0 测试通过:

#include <iostream>
using namespace std;

class copyFunc {
public:
	copyFunc(int xx = 0, int yy = 0) {
		X = xx;
		Y = yy;
		cout << "LocationA(int,int)有参数构造函数." << this << endl;
		;
	}

	//copy构造函数  完成对象的初始化
	copyFunc(const copyFunc & obj) //copy构造函数
			{
		X = obj.X;
		Y = obj.Y;
		cout << "copy构造函数. " << this << endl;
	}
	~copyFunc() {
		cout << X << "," << Y << "~LocationA()析构函数." << this << endl;
	}
	int GetX() {
		return X;
	}
	int GetY() {
		return Y;
	}
private:
	int X, Y;
};

copyFunc g() {
	copyFunc A(1, 2);
	return A;
}
//1.用一个对像A对去初始化一个对象B,会发生copy构造函数调用
void objplay10(){
	copyFunc A(2,4);
	copyFunc B = A;
}

//2.用一个对象A对另一个对象赋值,这不会发生copy构造函数调用
void objplay20(){
	copyFunc A(2,4);
	copyFunc B;
	B = A;
}

//3.显式的调用copy构造函数,进行对像初始化
void objplay30(){
	copyFunc A(3,4);
	copyFunc B(A);
}
//4.在函数中调用一个会创建匿名对象的函数g()
void objplay40() {
	g();
}

//5.用匿名对象初始化m 此时c++编译器 直接把匿名对转成m;(扶正) 从匿名转成有名字了m
//这里不会发生调用copy构造函数。
void objplay50() {
	copyFunc m = g();
}

//6.将匿名对像赋值给一个对象,此时会相当于创建了两个类对象,这里也不会发生copy函数的调用
void objplay60() {
	copyFunc m2(1, 2);
	m2 = g();

}

//7. 使用值传递,在函数参数中,相当于将实参初始化给了函数中的形参,所以会发生copy构造函数的调用。
void func70(copyFunc A) {}
void objplay70(){
	copyFunc A(4,5);
	func70(A);
}

int main() {
	//分别测试下面几个函数调用,观察copy构造函数的调用
	//objplay10();
	//objplay20();
	//objplay30();
	//objplay40();
	//objplay50();
	//objplay60();
	objplay70();
	cout << "end..." << endl;
	return 0;
}


深copy和浅copy测试代码,启用不同的copy方法,测试前后变化,如果不定义copy构造函数,默认的情况下,是浅copy。

/*
 * 深copy和浅copy.cpp
 *
 *  Created on: 2015年10月25日
 *      Author: xn666
 */

#include <iostream>
#include <string.h>
#include <stdlib.h>

using namespace std;

class mycopys{
public:

	mycopys(){
		p = NULL;
		len = 0;
		cout << "mycopys() call " << this <<endl;
	}
	mycopys(const char *_p){
		len = strlen(_p);
		p = (char *)malloc(sizeof(char)*(len+1));
		strcpy(p,_p);
		cout << "mycopys(*) call " << this <<endl;
	}
	mycopys(const mycopys & obj){
		    len = obj.len;
		    //p = obj.p; //浅copy
		    p = (char *)malloc(sizeof(char)*(len+1)); //深copy
		    strcpy(p,obj.p);
		    //strcpy(p,"dddd");//验证深copy和浅copy是不是同一块内存区
			cout << "mycopys(&) call " << this <<endl;
		}
	~mycopys(){
		if(p != NULL){
			free(p);
		}
		len = 0;
		cout << "~mycopys() call " << this <<endl;
	}
	char * get_chars(){
			return p;
		}
	int get_paddress(){
		return (int)p;
	}
protected:
private:
	char *p;
	int len;
};

void objplaymain_mycpys(){
	mycopys obj1("abcef");

	mycopys obj2 = obj1;
	printf("obj1:%p,obj2:%p\n",obj1.get_chars(),obj2.get_chars());
	printf("%s\n",obj1.get_chars());
	printf("%s\n",obj2.get_chars());
}
int main(){
	objplaymain_mycpys();
	cout << "end" << endl;
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值