日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言哆啦a梦用printf输出,【2013.1.20】故事的最后,哆啦A梦终于又回到了大雄身边。从此两个人过上了…——ProtoType...

發布時間:2024/9/19 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言哆啦a梦用printf输出,【2013.1.20】故事的最后,哆啦A梦终于又回到了大雄身边。从此两个人过上了…——ProtoType... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

// // // // // // // //?//

///2013.1.20

// // // // // // //?//?//

還記得小的時候看哆啦A夢,

里面有一話講到大雄用一個神奇的工具,

好像是一個燈之類的東西,

照一照點心,

點心就會自動復制到無限多(2^n)。

先不管這是不是一件讓人羨慕的事情,

但是這個道具,無意間實現了我們今天所要講的模式——Prototype。

【核心】使用復制(Clone)代替創建(new)對象。

UML圖表示:

從表面上看,

與其說是一個模式,

倒不如說是一種復制行為更為貼切。

然而,

這其中,卻隱藏著另一個難以察覺的問題。

它涉及到了對象拷貝的兩種方式:

——深拷貝與淺拷貝。

在探討這個兩種拷貝方式的區別之前,

首先要提到&這個運算符:

一般情況下,

它的使用方法與指針類似(但不是相等),

&a表示的是a的引用。

一個最簡單的使用方法如下所示:

void changeValue(const int& a)

{

a +=10;

}

int value = 10;

changeValue(value);

printf("%d",value);//輸出結果為20

一般函數傳遞的話,

并不可以直接修改實參的值,

然而我們可以利用傳遞實參的引用(即其地址)來做到這一點。

那么&這個運算符與Prototype有有什么關系呢?

其實,

在C++中,

即使是我們自定義的類,

也存在著一個看不到的復制構造函數,

它的寫法格式如下:

SomeClass(constSomeClass& C)

正因為存在著這個函數,

我們才能夠使用如下的方法進行對象之間的直接賦值創建:

SomeClass a;

SomeClass b(a);

這是非常方便的。

但是,

很遺憾,

默認的復制構造函數只是淺拷貝,

不是深拷貝。

二者大致的區別就是:

淺拷貝如果遇到動態變量(例如A類中聚合B類對象),就不能正確工作了,因為它只是將地址的引用傳給了另一個對象,并沒有另外開辟一段內存。

深拷貝就是從這方面著想,對內存實實在在地進行了第二份拷貝(而不是耍小聰明只是傳個引用)。

具體深拷貝與淺拷貝的區別可以看這篇文章:http://blog.csdn.net/bluescorpio/article/details/4322682

因此,

我們實現ProtoType的時候,

最值得注意的地方就是要創建適用于自己類的復制構造函數,

而不僅僅只是使用C++默認的那個。

具體代碼實例:

【大致思路】

虛基類Dessert類的兩個派生類分別使用了深克隆與淺克隆的方法,可以在他們同樣調用copyDessert之后輸出的結果中看出來這兩種克隆方法的差異。

Dessert.h

#ifndef _DESSERT_H_

#define _DESSERT_H_

class Dessert

{

public:

Dessert(){}

~Dessert(){}

virtual Dessert* copyDessert() = 0;

virtual void outputNum() = 0;

};

class DessertWithDepCopy:public Dessert

{

public:

DessertWithDepCopy();

DessertWithDepCopy(const DessertWithDepCopy& con);

~DessertWithDepCopy();

static int dessertNum;

Dessert* copyDessert();

void outputNum();

};

//Didn't define the copy constructor(Use default).

class DessertWithShallowCopy:public Dessert

{

public:

DessertWithShallowCopy();

~DessertWithShallowCopy();

static int dessertNum;

Dessert* copyDessert();

void outputNum();

};

#endif

Dessert.cpp

#include "Dessert.h"

#include

int DessertWithDepCopy::dessertNum = 0;

int DessertWithShallowCopy::dessertNum = 0;

//DeepCopy class's defination.

DessertWithDepCopy::DessertWithDepCopy()

{

dessertNum++;

}

DessertWithDepCopy::DessertWithDepCopy(const DessertWithDepCopy& con)

{

dessertNum++;

}

DessertWithDepCopy::~DessertWithDepCopy()

{

if(--dessertNum < 0)

dessertNum = 0;

}

Dessert* DessertWithDepCopy::copyDessert()

{

return new DessertWithDepCopy(*this);

}

void DessertWithDepCopy::outputNum()

{

std::cout<

}

//ShallowCopy class's defination.

DessertWithShallowCopy::DessertWithShallowCopy()

{

dessertNum++;

}

DessertWithShallowCopy::~DessertWithShallowCopy()

{

if(--dessertNum < 0)

dessertNum = 0;

}

Dessert* DessertWithShallowCopy::copyDessert()

{

return new DessertWithShallowCopy(*this);

}

void DessertWithShallowCopy::outputNum()

{

std::cout<

}

main.cpp

#include"Dessert.h"

#include

enum

{

Deep,

Shallow

};

int main()

{

Dessert* dessert[2];

dessert[Deep] = new DessertWithDepCopy();

dessert[Shallow] = new DessertWithShallowCopy();

std::cout<

dessert[Deep]->outputNum();

dessert[Shallow]->outputNum();

Dessert* newDessert[2];

//Copy construtor.

newDessert[Deep] = dessert[Deep]->copyDessert();

newDessert[Shallow] = dessert[Shallow]->copyDessert();

std::cout<

dessert[Deep]->outputNum();

dessert[Shallow]->outputNum();

return 0;

}

輸出結果:

【注意事項】

如上圖所示,在調用copyDessert方法之后,淺克隆的數量卻沒有增加,但這與我們程序的原有設想是相違背的。

因此,在自己編寫的類中,要記得對復制構造函數進行override,從而降低Bug發生概率。

總結

以上是生活随笔為你收集整理的C语言哆啦a梦用printf输出,【2013.1.20】故事的最后,哆啦A梦终于又回到了大雄身边。从此两个人过上了…——ProtoType...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。