设计模式之原型模式学习

由于没有接触过C#,不知《大话设计模式》所云。但无看了《大话设计模式》觉得非就是深拷贝和浅拷贝的问题。在此谈谈我对C++深拷贝与浅拷贝的认识,不足之处请指出。

对编程来说简单的复制粘贴极有可能造成重复代码的灾难,也很容易造成存在问题的代码的传播。

原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型对象创建新的对象。

通俗的说就是从一个对象再创建另一个可定制的对象,而且不知道任何创建的细节。

拷贝分为浅拷贝和深拷贝。浅拷贝是C++默认的拷贝方式。通过逐个成员赋值的方式来实现的。比如对类

class Time

{

  public:

int month;

int day;

int year;

};

如有Time a;

Time b=a;
//或是Time b(a);

此时将会调用复制构造函数,采用将a的成员变量逐个赋值给b对应的成员变量的浅拷贝方式。类似的情况还有Timeb;b=a;与上面代码的区别在于b多调用一次默认构造函数,在b=a是调用的是默认的重载赋值运算符函数。Timeb=a;仍是调用的复制构造函数,而不是调用重载的赋值运算符函数,这一点要清楚。

复制构造函数和默认的赋值运算符采取的就是浅拷贝的方式。调用复制构造函数有以下几种情况:一:按值传递对象时。二:函数返回对象时。三:用一个对象初始化另一个对象时Timea(b),或是Timea=bC++默认的赋值和复制构造函数中都是浅拷贝,如果需要深拷贝的话需要自己实现。

对于一般的成员变量浅拷贝与深拷贝没有本质的区别,而对于类中包含动态分配内存的指针类型的成员变量时,逐个成员赋值可能会引发严重的问题。此时两个对象的指针成员变量指向相同的堆空间,一旦有一个对象将此空间释放,另一个再次访问将会发生访问违规的情况,导致程序非正常终止。可以通过重写赋值运算符函数和复制构造函数来实现深拷贝。

实现深拷贝时,如b=a,会在堆中开辟另一块空间,它与a的成员变量ptr指向的堆空间存储的内容完全相同。开辟的新的堆空间的首地址赋值给bptr。就实现了每个对象的的ptr指向不同的堆空间,其中一个对象的堆空间释放与否不会对另一个对象造成影响。

#include<iostream>
using namespace std;
class A
{
	public: 
	  int a;
	  int *b;
	public:
      A()
      {
      	a=0;
      	b=new int;
      	*b=0;
      }
	  A(int aa,int bb)
	  {
	  	a=aa;
	  	b=new int;
	  	*b=bb;
  		
  	  }
  	  A(A& aa)
  	  {
  	  	b=new int;
  	  	a=aa.a;
  	  	*b=*aa.b;
  	  }
};
int main(int argc,char**argv)
{
	A AA(20,40);
	A BB(AA);
	A CC;//A CC=AA;等同于A CC(AA);
	CC=AA;
	cout<<AA.a<<", "<<*AA.b<<endl;
	cout<<BB.a<<", "<<*BB.b<<endl;
	cout<<CC.a<<", "<<*CC.b<<endl;
	*AA.b=80;
	cout<<AA.a<<", "<<*AA.b<<endl;
	cout<<BB.a<<", "<<*BB.b<<endl;
	cout<<CC.a<<", "<<*CC.b<<endl;
	
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值