2023年全國(guó)碩士研究生考試考研英語(yǔ)一試題真題(含答案詳解+作文范文)_第1頁(yè)
已閱讀1頁(yè),還剩22頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、<p>  畢業(yè)設(shè)計(jì)外文資料翻譯</p><p>  學(xué) 院: 信息科學(xué)與工程學(xué)院 </p><p>  專 業(yè): 計(jì)算機(jī)科學(xué)與技術(shù) </p><p>  姓 名: </p&

2、gt;<p>  學(xué) 號(hào): </p><p>  外文出處:Norbert PATAKI,F(xiàn)aculty of Electrical Engineering and Informatics, Technical University of Ko?ice,Versita Open,2011 :1335-8243 &l

3、t;/p><p>  附 件: 1.外文資料翻譯譯文;2.外文原文。 </p><p>  附件1:外文資料翻譯譯文</p><p><b>  隱蔽方法在C++</b></p><p>  摘要:如今復(fù)雜的軟件系統(tǒng)的設(shè)計(jì)和實(shí)施的主要面向?qū)ο蟮姆妒降膸椭H欢?,面向?qū)ο蟮恼Z(yǔ)言支持不同的方式與不同的結(jié)構(gòu)面向?qū)ο蟮姆独?

4、#160;C + +中有一個(gè)精良的傳承符號(hào)的基礎(chǔ)上的訪問修飾符。 C + +的區(qū)別虛擬的,純粹的虛擬和非虛擬方法。 Java的使用final的類和方法來禁用繼承。然而,Java不支持多重繼承。艾菲爾允許重命名繼承的方法。在本文中我們提出的一些方法公用程式C + +中創(chuàng)建更安全和更靈活的面向?qū)ο蟮南到y(tǒng)。我們提出如何與C + +的模板設(shè)施的幫助下實(shí)施。我們目前的情況下,可以編寫更安全的代碼,我們構(gòu)造。 關(guān)鍵詞:C+

5、+,方法,面向?qū)ο缶幊?,模?lt;/p><p>  引言 面向?qū)ο缶幊蹋∣OP)仍是最常見的編程范式。它代表企圖以使程序更加緊密地塑造人們的思維方式和處理與世界。在編程的舊樣式,一名程序員面臨著一些問題,必須確定一個(gè)計(jì)算任務(wù),需要執(zhí)行為了解決這個(gè)問題。在這種方式中,編程包括找到一個(gè)指令序列,將完成這項(xiàng)任務(wù)。在面向?qū)ο蟮木辰?,而不是我們找?duì)象 - 實(shí)體,有行為的任務(wù),持有信息,并且可以彼此互動(dòng)。編程由一組對(duì)象

6、的設(shè)計(jì)模式的問題。在程序中的軟件對(duì)象可以代表在問題域的真實(shí)或抽象的實(shí)體[12]。這是應(yīng)該使設(shè)計(jì)方案更自然因此更容易得到正確的和更容易理解。許多編程語(yǔ)言支持objectorientationSimula的67是第一語(yǔ)言支持這一論斷。語(yǔ)言,如C +,C#和Java時(shí)下最有名的。艾菲爾已被開發(fā)貝特朗·邁耶在1986年[11],這是也面向?qū)ο蟮恼Z(yǔ)言。腳本語(yǔ)言通?;诿嫦?qū)ο蟮姆独H欢?,?duì)于例如當(dāng)前版本支持的PHP的OOP。事實(shí)上,不

7、同的語(yǔ)言支持不同的這種范式結(jié)構(gòu)[8]。這些構(gòu)造的高度分析和互相比較,因?yàn)槠占懊嫦驅(qū)ο缶幊谭妒絒3,6,7,9]。例如,C + +不具有的每一個(gè)的超類類,但在Java Object類是類層次的根。C + +</p><p>  2.UNHIDABLE方法</p><p>  這是常見的錯(cuò)誤,在C+ +的虛擬簽名在基類和派生類的方法不同意。在這虛擬方法不能重寫,但隱藏。讓我們考慮以下代碼片段:

8、</p><p><b>  struct X</b></p><p><b>  {</b></p><p>  virtual void f()</p><p><b>  {</b></p><p>  std::cout << &qu

9、ot;X::f()" << std::endl;</p><p><b>  }</b></p><p>  virtual ~X() {}</p><p><b>  };</b></p><p>  struct Y:X</p><p><b&

10、gt;  {</b></p><p>  virtual void f() const</p><p>  {std::cout << "Y::f()" << std::endl;</p><p><b>  }</b></p><p><b>  };&

11、lt;/b></p><p>  int main()</p><p><b>  {</b></p><p>  X* x = new X();</p><p><b>  x->f();</b></p><p><b>  delete x;<

12、/b></p><p>  x = new Y();</p><p><b>  x->f();</b></p><p><b>  delete x;</b></p><p><b>  }</b></p><p>  The output

13、 of this program is the following:</p><p><b>  X::f()</b></p><p><b>  X::f()</b></p><p>  此輸出似乎是奇怪的。問題的根源是虛方法的簽名是不完全的在基地和派生類中的相同。有一個(gè)const修飾符在課堂上Y.應(yīng)盡量避免這種情況。然

14、而,編譯器沒有錯(cuò)誤消息編譯此代碼,只他們中的一些給予警告。為了克服這種情況我們利用C + +模板設(shè)施和預(yù)處理用于方便地使用我們的解決方案。首先,我們包裝成一個(gè)成員函數(shù)指針模板類:#define __PTR_MEM(paramlist) template \</p><p>  <class T> \</p><p>  struct __Ptr_Mem \</p>

15、<p><b>  { \</b></p><p>  void (T::*p)paramlist; \</p><p><b>  };</b></p><p>  之后,我們創(chuàng)建的測(cè)試模板類的實(shí)例以前的模板。如果這個(gè)測(cè)試類檢查兩個(gè)包裹指針可以分配給對(duì)方。如果基類和派生類的方法的簽名是在完全相同的,那么這個(gè)

16、任務(wù)正常工作。但是,如果簽名是不一樣的,那么這個(gè)分配結(jié)果編譯錯(cuò)誤信息,它不能被轉(zhuǎn)換。#define __TEST(funcname) template \</p><p>  <class Base, class Der> \</p><p>  struct __Test \</p><p><b>  { \</b></

17、p><p>  __Ptr_Mem<Base> a; \</p><p>  __Ptr_Mem<Der> b; \</p><p>  __Test() \</p><p><b>  { \</b></p><p>  a.p = &Base::funcname;

18、\</p><p>  b.p = &Der::funcname; \</p><p><b>  } \</b></p><p><b>  };</b></p><p>  這些宏后,我們開發(fā)的宏啟動(dòng)檢查此功能。宏調(diào)用以前的宏,創(chuàng)建一個(gè)匿名的命名空間的新方法,稱為測(cè)試,如果隱藏的方法,它

19、調(diào)用測(cè)試模板的如果簽名的默認(rèn)構(gòu)造函數(shù)和檢查相同:#define TEST_IF_HIDDEN_METHODS( Base, Der, \</p><p>  function, paramlist) \</p><p>  namespace { \</p><p>  __PTR_MEM(paramlist) \</p><p>  __

20、TEST(f) \</p><p>  void __test_if_hidden_methods() \</p><p><b>  { \</b></p><p>  __Test<Base, Der>(); \</p><p><b>  } \</b></p>&l

21、t;p><b>  }</b></p><p>  讓我們考慮如何才能使用此解決方案禁用在本節(jié)第一個(gè)例子中隱藏的虛擬方法:TEST_IF_HIDDEN_METHODS(X,Y F,()),這個(gè)宏必須呼吁在全球空間。如果代碼編譯,然后簽名是在相同的基礎(chǔ)和派生類,這意味著虛擬方法的正確使用。這將導(dǎo)致一個(gè)最小的開銷,因?yàn)樗鼊?chuàng)建了一個(gè)全球測(cè)試對(duì)象,并執(zhí)行兩個(gè)任務(wù)之間兩個(gè)成員的三分球在運(yùn)行時(shí),

22、這是廉價(jià)的操作。否則,代碼不編譯,結(jié)果在以下錯(cuò)誤消息:error: cannot convert 'void (X::*)()'</p><p>  to 'void (Y::*)()const'</p><p>  in assignment在本節(jié)中,我們提供了一個(gè)解決方案,以避免問題隱藏的虛擬方法時(shí)出現(xiàn)簽名一種方法是不一樣的,在基地和派生類。3.法

23、重新命名 在艾菲爾編程語(yǔ)言繼承可以改名功能。當(dāng)兩種方法繼承從不同的基類具有相同的名稱,這門語(yǔ)言元素有助于避免在派生類中的模糊性。雖然這是強(qiáng)制性的,在艾菲爾歧,C + +允許我們重新定義這兩種方法,一次作為一個(gè)單一的方法派生類。它可以發(fā)生,但是,這兩個(gè)基地類代表不同的概念,名稱沖突只是巧合。然后,我們可能要重新定義那些在派生類中的語(yǔ)義不同的方法(ES)分別只是想,如果他們有沒有任何共同之處。通過簡(jiǎn)單的例子,我們展示了如何重新命名繼

24、承的方法,在C + +,從而能夠覆蓋同樣的命名方法分開。設(shè)A和B是我們每一個(gè)都有一個(gè)基類方法foo:struct A</p><p><b>  {</b></p><p>  virtual void foo();</p><p><b>  };</b></p><p><b>  

25、{</b></p><p>  virtual void foo();</p><p><b>  };</b></p><p>  and a derived class C:</p><p>  struct C : public A, public B</p><p><b

26、>  {</b></p><p>  virtual void foo(); // overrides both</p><p><b>  };</b></p><p>  Instead of merging the two methods into one we would</p><p>  l

27、ike to have separate methods, one for each inherited foo:</p><p>  struct C : public A, public B</p><p><b>  {</b></p><p>  virtual void A_foo();</p><p>  v

28、irtual void B_foo();</p><p><b>  };</b></p><p>  We can achieve that by introducing two extra helper</p><p>  classes, one for each base class, whose purpose is to renam

29、e</p><p>  A::foo to A foo and B::foo to B foo respectively.</p><p>  For symmetry reasons we present only RenA:</p><p>  struct RenA : public A</p><p><b>  {<

30、/b></p><p>  virtual void A_foo() { A::foo(); }</p><p>  virtual void foo() { A_foo(); }</p><p><b>  }</b></p><p>  4. final方法</p><p> 

31、 在Java編程語(yǔ)言,它可以聲明作為最后的成員函數(shù)[5]。這意味著,該成員功能不能在子類中重寫。有兩個(gè)好處:第一,涉及到程序設(shè)計(jì)和代碼的質(zhì)量,第二個(gè)屬于性能(編譯器可以內(nèi)聯(lián)這些功能)。在C + +編程語(yǔ)言,有良好的機(jī)制,使函數(shù)內(nèi)聯(lián),但沒有任何語(yǔ)言的支持,以防止在子類中重寫虛擬成員函??數(shù)。Stroustrup的等。等。 [22]提出了一種解決方案,以阻止派生一類。在本章中,我們展示了解決方案,使一個(gè)C + +虛成員函數(shù)uno

32、verridable。讓我們假設(shè)我們有一個(gè)虛擬成員函??數(shù)與基類AF(),我們希望它的“最終”。在休息節(jié)中,我們假設(shè)是動(dòng)態(tài)創(chuàng)建的對(duì)象,因?yàn)樵贑 + +的多態(tài)性由指針。它作品也通過引用,但我們的解決方案是有限的指針。我們今后的工作之一,是把它擴(kuò)大到作為參考好。首先,我們需要制定出每類對(duì)象A或A的子類必須創(chuàng)建一個(gè)具體的工廠函數(shù),而不是編寫新的。這家工廠功能檢查是否函數(shù)f()重寫。如果不是,它創(chuàng)建一類的新實(shí)例,否則會(huì)發(fā)出編譯時(shí)錯(cuò)誤消息和編譯失

33、敗。實(shí)現(xiàn)為此,我們有私人經(jīng)營(yíng)的新定義在類,并宣布為朋友的工廠函數(shù)。我們需要一個(gè)輔助類,它描述了成員功能作出最后。見下文:templ</p><p>  class Helper { };</p><p>  第一個(gè)模板參數(shù)是一個(gè)任意類型,第二個(gè)一個(gè)是適當(dāng)?shù)某蓡T函數(shù)的指針。模板<class T>結(jié)構(gòu)的最終檢查T類是否有不同的成員函數(shù)f一:: f()的方法如下

34、:template <class T></p><p>  struct Final</p><p><b>  {</b></p><p><b>  Final()</b></p><p><b>  {</b></p><p>  c

35、onst bool b =</p><p>  boost::is_same<</p><p>  Helper<A, &A::f>,</p><p>  Helper<A, &T::f> >::value;</p><p>  BOOST_MPL_ASSERT_MSG(</p>

36、<p><b>  b,</b></p><p>  ERROR_INVALID_OVERRIDE_OF_FUNCTION,</p><p><b>  (void)</b></p><p><b>  );</b></p><p><b>  }<

37、;/b></p><p><b>  };</b></p><p>  原理功能是相同的[10] boost庫(kù)提供,而且它的兩個(gè)模板參數(shù)在編譯時(shí)檢查是否是相同的。宏升壓的MPL的ASSERT味精[10]創(chuàng)建一個(gè)編譯時(shí)錯(cuò)誤消息時(shí),它的第一個(gè)參數(shù)是假的。第二個(gè)參數(shù)是錯(cuò)誤信息,第三個(gè)擁有某種類型的信息,這是不有必要在這里。如果T是A和子類的成員函數(shù)f不是ov

38、eridden在T,則T:: f是相同的成員功能,從而為A:: F兩個(gè)輔助類有相同的類型。工廠的功能如下:template<typename T></p><p>  T* factory()</p><p><b>  {</b></p><p>  Final<T>();</p><p

39、>  T* t = new T();</p><p><b>  return t;</b></p><p>  }如果它可以創(chuàng)建臨時(shí)最終<T>對(duì)象,這意味著該成員函數(shù)f是不被覆蓋。否則最終構(gòu)造的Boost MPL的斷言味精導(dǎo)致一個(gè)編譯錯(cuò)誤。這些源代碼的大部分是由預(yù)處理產(chǎn)生宏在下列方式:結(jié)構(gòu)Astruct A</p>&

40、lt;p><b>  {</b></p><p>  virtual void f() {}</p><p>  PREPARE_FINAL_METHODS</p><p><b>  };</b></p><p>  SET_FINAL(A, f, void, ())SET_FINAL(A,

41、F,無效的,())宏準(zhǔn)備final方法產(chǎn)生的私人運(yùn)營(yíng)商新功能的朋友聲明工廠。宏集最終(A,F(xiàn),無效的,())作為最后一個(gè)成員函數(shù)的成員函數(shù)f。宏的第一個(gè)參數(shù)是類,第二個(gè)是功能,第三個(gè)什么返回類型,而最后一個(gè)是參數(shù)類型列表。我們提供集FINALn預(yù)處理宏定義多個(gè)成員函數(shù)到:最后更新,N表示成員函數(shù)設(shè)置到最后這個(gè)宏有四個(gè)參數(shù)列印倍。(四,每個(gè)成員函數(shù)想在前面的例子。)下面的例子顯示了這個(gè)復(fù)雜的用法解決方案:struct A</p

42、><p><b>  {</b></p><p>  virtual void f() { /* ... */ }</p><p>  virtual int g(int, double) { /* ... */ }</p><p>  virtual char h() { /* ... */ }</p>&l

43、t;p>  virtual void k() { /* ... */ }</p><p>  PREPARE_FINAL_METHODS</p><p><b>  };</b></p><p>  SET_FINAL3(A, f, void, (),</p><p>  A, g, int, (int, doub

44、le),</p><p>  A, h, char, () )</p><p>  struct B : A</p><p><b>  {</b></p><p>  int g(int, double) { /* ... */ }</p><p><b>  };</b>

45、</p><p>  struct C : A</p><p><b>  {</b></p><p>  void k() { /* ... */ }</p><p><b>  };</b></p><p>  int main()</p><p>

46、;<b>  {</b></p><p>  B* b = factory<B>(); // ERROR</p><p>  C* c = factory<C>(); // OK</p><p><b>  }</b></p><p>  設(shè)置FINAL3宏創(chuàng)建的具體幫手最終

47、類和工廠功能的成員函數(shù)F,G和?,我們當(dāng)前要設(shè)定最后更新。該結(jié)構(gòu)乙覆蓋結(jié)構(gòu)的一個(gè)成員函數(shù)?和結(jié)構(gòu)ç也與成員函數(shù)K表相同。當(dāng)我們當(dāng)前要?jiǎng)?chuàng)建一個(gè)乙的實(shí)例,我們得到以下錯(cuò)誤消息:</p><p>  assertion_failed(mpl_::failed************</p><p>  (Final<R>::Final() [with R = C]::<

48、;/p><p>  ERROR_INVALID_OVERRIDE_OF_FUNCTION</p><p>  ::************)</p><p>  出現(xiàn)此錯(cuò)誤信息,因?yàn)榻Y(jié)構(gòu)乙覆蓋其基類一個(gè)Hovewer至少有一個(gè)最后更新的成員函數(shù)成員,因?yàn)槲覀儺?dāng)前可以建立一個(gè)實(shí)例結(jié)構(gòu)ç?是不是最終的功能。5.結(jié)論與未來工作 在本文中,我們提出了不同的實(shí)

49、現(xiàn)面向?qū)ο蟮奶匦栽诘腃 ++不提供局域網(wǎng)有瓜葛的構(gòu)造。這些功能使開發(fā)變得更容易,更安全,更靈活。 final類的想法來從Java和其實(shí)施的C + +的優(yōu)勢(shì)模板。 unhidable方法的想法來自一個(gè)常見的錯(cuò)誤時(shí),繼承和重載。該解決方案還采用了C + +模板的構(gòu)建。定義的最后一個(gè)成員函數(shù)是既有益設(shè)計(jì)和效率的原因。雖然C + +編程語(yǔ)言不支持它本身,我們提出如何運(yùn)用這個(gè)面向?qū)ο蟮奶攸c(diǎn),在解決方案的C + +。在當(dāng)前的研究

50、與開發(fā)階段是有限制設(shè)置成員函數(shù)作為最后:如果有一個(gè)成員設(shè)置為最終沒有基類中的函數(shù)(F)允許創(chuàng)建一個(gè)派生類的成員函數(shù)f即使有不同的參數(shù)類型。我們今后的工作是提高我們的解決方案,以消除此限制。</p><p>  附件2:外文原文(復(fù)印件)</p><p>  Subtle Methods in C++ </p><p>  Vol. 11, No. 3, 2011,

51、11–16, DOI: 10.2478/v10198-011-0023-x 11</p><p>  SUBTLE METHODS IN C++</p><p>  Zala´n SZU? GYI, Norbert PATAKI, Jo´zsef MIHALICZA</p><p>  Department of Programming Lang

52、uages and Compilers, E¨otv¨os Lor´and University, P´azm´any P´eter s´et´any 1/C, H-1117 Budapest,</p><p>  Hungary, e-mail: lupin@ludens.elte.hu, patakino@elte.hu, jmi

53、halicza@gmail.com</p><p>  ABSTRACT: Nowadays complex software systems are designed and implemented with the help of the object-oriented paradigm principally. However, object-oriented languages support the o

54、bject-oriented paradigm in different ways with different constructs. C++ has a sophisticated inheritance notation based on access modifiers. C++ distinguishes virtual, pure virtual and non-virtual methods. Java uses fina

55、l classes and methods to disable inheritance. However, Java does not support multiple inheritance. E</p><p>  In this paper we present some method utilities for C++ to create safer and more flexible object-o

56、riented systems. We present how the method renaming can be implemented. We developed constructs to create final and unhittable methods. These constructs are implemented with the help of C++ template facilities. We presen

57、t scenarios where one can write safer code with our constructs.</p><p>  Keywords: C++, methods, object-oriented programming, template</p><p>  1. INTRODUCTION</p><p>  Object-orien

58、ted programming (OOP) is still the most common programming paradigm. It represents an attempt</p><p>  to make programs more closely model the way people think about and deal with the world. In the older sty

59、les of programming, a programmer who is faced with some problem must identify a computing task that needs to be performed in order to solve the problem. In this way, programming consists of finding a sequence of instruct

60、ions that will accomplish that task. In the object-oriented realm instead of tasks we find objects - entities that have behaviors, that hold information, and that can interact </p><p>  supports the object-o

61、riented paradigm [18]. Multiple inheritances allowed, but there is no language construct for</p><p>  final classes, final methods, or renaming methods [2]. In C++, a method in a base class is hidden, when a

62、 method</p><p>  is declared in a derived class with the same name but with different parameter types and/or consents [16]. Although, this can be avoided with using declarations, this scenario is strange [12

63、].C++ offers the template construct for writing generic functions and classes. However, a new direction has been developed with this construct called template met programming(TMP). Met programs – among other advantages–

64、are able to check conditions in compilation time. If the condition fails, the compilation </p><p>  case the virtual methods are not overridden, but hidden. Lotus consider the hereinafter code snippet:</p

65、><p><b>  struct X</b></p><p><b>  {</b></p><p>  virtual void f()</p><p><b>  {</b></p><p>  std::cout << "X::

66、f()" << std::endl;</p><p><b>  }</b></p><p>  virtual ~X() {}</p><p><b>  };</b></p><p>  struct Y:X</p><p><b>  {

67、</b></p><p>  virtual void f() const</p><p>  {std::cout << "Y::f()" << std::endl;</p><p><b>  }</b></p><p><b>  };</b&

68、gt;</p><p>  int main()</p><p><b>  {</b></p><p>  X* x = new X();</p><p><b>  x->f();</b></p><p><b>  delete x;</b>

69、</p><p>  x = new Y();</p><p><b>  x->f();</b></p><p><b>  delete x;</b></p><p><b>  }</b></p><p>  The output of th

70、is program is the following:</p><p><b>  X::f()</b></p><p><b>  X::f()</b></p><p>  This output seems to be strange. The source of the problem is that the si

71、gnature of virtual method is not exactly the same in base and in derived class. There is a const modifier in class Y. This situation should be avoided. However, the compilers compile this code without error message and o

72、nly some of them give a warning. To overcome this situation we take advantage of C++ templates facility and preprocessors used for making our solution convenient to use. First, we wrap a pointer to a member </p>&

73、lt;p>  template class:</p><p>  #define __PTR_MEM(paramlist) template \</p><p>  <class T> \</p><p>  struct __Ptr_Mem \</p><p><b>  { \</b></p&

74、gt;<p>  void (T::*p)paramlist; \</p><p><b>  };</b></p><p>  After that, we create the tester template class that instantiates the previous template. This tester class checks

75、 if the</p><p>  two wrapped pointers can be assigned to each other. If the signature of method of base and derived class is the exactly the same, then this assignment works properly. But, if the signatures

76、are not the same, then this assignment results compilation error message, that it cannot be converted.</p><p>  #define __TEST(funcname) template \</p><p>  <class Base, class Der> \</p

77、><p>  struct __Test \</p><p><b>  { \</b></p><p>  __Ptr_Mem<Base> a; \</p><p>  __Ptr_Mem<Der> b; \</p><p>  __Test() \</p>&

78、lt;p><b>  { \</b></p><p>  a.p = &Base::funcname; \</p><p>  b.p = &Der::funcname; \</p><p><b>  } \</b></p><p><b>  };</b&g

79、t;</p><p>  After these macros, we develop the macro that start to check this feature. Macro calls the previous macros, and creates a new method in the anonymous namespace, called test if hidden methods, whi

80、ch calls the Test template’sdefault constructor and checks if the signatures are same:</p><p>  #define TEST_IF_HIDDEN_METHODS( Base, Der, \</p><p>  function, paramlist) \</p><p> 

81、 namespace { \</p><p>  __PTR_MEM(paramlist) \</p><p>  __TEST(f) \</p><p>  void __test_if_hidden_methods() \</p><p><b>  { \</b></p><p>  __T

82、est<Base, Der>(); \</p><p><b>  } \</b></p><p><b>  }</b></p><p>  Let us consider how can one use this solution to disable hide the virtual method in

83、this section very first example:</p><p>  TEST_IF_HIDDEN_METHODS( X, Y, f, () )</p><p>  This macro must be called in the global space. If the code compiles, then the signature is the same in ba

84、se and</p><p>  derived class, which means proper usage of virtual methods. This causes a minimal overhead, because it creates a</p><p>  global Test object and executes two assignment between t

85、wo member-to-pointers at runtime, which is cheap operation. Otherwise, the code does not compile, results in the following error message:</p><p>  error: cannot convert 'void (X::*)()'</p><

86、;p>  to 'void (Y::*)()const'</p><p>  in assignment</p><p>  In this section we provide a solution to avoid the problem of hidden virtual methods, which appears when the signature of

87、a method is not the same in the base and derived class.</p><p>  3. METHOD RENAMING</p><p>  In the Eiffel programming language the inherited features can be renamed. When two methods inherited

88、from different base classes have the same name this language element helps to avoid ambiguity in the derived class.</p><p>  While this disambiguation is compulsory in Eiffel, C++ allows us to redefine both

89、methods once as a single method of the derived class. It can happen, however, that the two base classes represents different concepts, and the name clash is simply coincidental. Then we may want to redefine those semanti

90、cally different methods in the derived class(es) separately just like if they had nothing in common. Through simple example we show how to rename inherited methodsin C++ and thus be able to overrid</p><p>&

91、lt;b>  struct A</b></p><p><b>  {</b></p><p>  virtual void foo();</p><p><b>  };</b></p><p><b>  struct B{</b></p>

92、<p>  virtual void foo();</p><p><b>  };</b></p><p>  and a derived class C:</p><p>  struct C : public A, public B</p><p><b>  {</b></p

93、><p>  virtual void foo(); // overrides both</p><p><b>  };</b></p><p>  Instead of merging the two methods into one we wouldlike to have separate methods, one for each inh

94、erited foo:</p><p>  struct C : public A, public B</p><p><b>  {</b></p><p>  virtual void A_foo();</p><p>  virtual void B_foo();</p><p><b

95、>  };</b></p><p>  We can achieve that by introducing two extra helperclasses, one for each base class, whose purpose is to rename</p><p>  A::foo to A foo and B::foo to B foo respectiv

96、ely. For symmetry reasons we present only RenA:</p><p>  struct RenA : public A</p><p><b>  {</b></p><p>  virtual void A_foo() { A::foo(); }</p><p>  virtu

97、al void foo() { A_foo(); }</p><p><b>  };</b></p><p>  By default A foo behaves like A::foo. This way if A foo is not overridden, its calls through the derived classes will call foo’

98、s original implementation in A. On the other hand, a call to foo through a pointer or reference to A. Should result in a call to A foo, this is the actual renaming step. Calls to foo through the base class interface lead

99、s, the execution to the implementation of A foo either in this or in the appropriate derived class. Note that it is advisable to set foo final in this cl</p><p>  a method can be found in 4.Having this renam

100、e helper class implemented for B as well there is nothing more left than changing the base classes of C from A to Ren A and from B to Ren B respectively:</p><p>  struct C : public Ren A, public Ren B</p&

101、gt;<p>  Now we can use the renamed methods in C as if they</p><p>  were the original.</p><p>  This solution nicely fits to other features in connection with method overriding. The over

102、ridden version of A foo</p><p>  can for example call its original implementation in A by simply calling A::foo just like if we did not have the helper</p><p><b>  class:</b></p&g

103、t;<p>  void A_foo()</p><p><b>  {</b></p><p>  // added code</p><p>  A::foo(); // can simply call</p><p>  // base if needed</p><p>  

104、// added code</p><p><b>  }</b></p><p>  A caveat with the helper class that one should implement do-nothing forwarders for each constructor in it to make them available in the deriv

105、ed class. In C++ the constructor’sinitializer list is allowed to refer only to direct base classes. With a few lines of preprocessing multiprogramming (see boost.preproc [10]) an even more comfortable</p><p>

106、;  syntax can be achieved:</p><p>  struct A { ... };</p><p>  DEF_RENAMER(RenA, A,</p><p>  ((foo) (A_foo))</p><p>  // ((bar) (A_bar)) // we can add more</p>&

107、lt;p>  // renames easily</p><p><b>  )</b></p><p>  // similarly for B</p><p>  struct C : public RenA, public RenB { ... };</p><p>  4. FINAL METHODS<

108、;/p><p>  In the Java programming language it is possible to declare member function as final [5]. It means that the member function cannot be overridden in subclasses. There are two benefits of that: first is

109、concerning to the program design and the code quality, the second belongs to the performance(compiler can inline these functions). In the C++programming language there are good mechanisms to make functions inline, but th

110、ere is no language support to prevent overriding virtual member functions in sub</p><p>  We need a helper class, which describes the member function to make final. See below: template <class C, void (C::

111、*p)()>class Helper { };The first template argument is an arbitrary type and the second one is a pointer to the proper member function. The template<class T> struct Final checks whether the class T has different

112、member function f fromA::f() in the following way:</p><p>  template <class T></p><p>  struct Final</p><p><b>  {</b></p><p><b>  Final()</b

113、></p><p><b>  {</b></p><p>  const bool b =</p><p>  boost::is_same<</p><p>  Helper<A, &A::f>,</p><p>  Helper<A, &T::f

114、> >::value;</p><p>  BOOST_MPL_ASSERT_MSG(</p><p><b>  b,</b></p><p>  ERROR_INVALID_OVERRIDE_OF_FUNCTION,</p><p><b>  (void)</b></p>

115、;<p><b>  );</b></p><p><b>  }</b></p><p><b>  };</b></p><p>  Met function is same [10] is provided by the boost library, and it checks i

116、n compile time whether its two template arguments are the same. The macro BOOST MPL ASSERT MSG[10] creates a compile time error message when its first arguments false. The second argument is the error message, and the th

117、ird one holds some type information which is not necessary here. If T is subclass of A and the member function is not overridden in T then T::f is the same member function as A::f, thus the two Helper clas</p><

118、;p>  template<typename T></p><p>  T* factory()</p><p><b>  {</b></p><p>  Final<T>();</p><p>  T* t = new T();</p><p><b>

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論