2013-11-15 48 views
2

我不知道這是可以在C++中做的,直到我看到它。 AddAttribute(),AddTraceSource()等是類TypeId的成員函數。在創建對象/類期間調用對象/類的多個成員函數

TypeId 
Sender::GetTypeId (void) 
{ 
static TypeId tid = TypeId ("Sender") 
.SetParent<Application>() /*Member function of TypeId*/ 
.AddConstructor<Sender>() 
.AddAttribute ("PacketSize") 
.AddAttribute ("Destination") 
.AddTraceSource ("Tx") 
; 
return tid; 
} 

我從來不知道我們可以在C++中做到這一點。 是否有人可以在這個主題上拋出更多的光線(在對象創建期間調用多個成員函數)?我知道我們可以在腳本中做到這一點。但在C++?該文件具有擴展名* .cc。對不起,如果我的問題是天真的,而事實證明我錯過了閱讀C++中的幾章?!

+0

你從哪裏拿這段代碼?沒有任何進一步的背景知識,很難理解它的作用。 – bitgarden

+0

感謝您的回覆!此代碼片段來自ns3模擬器(nsnam.org) – recursion1212

+0

感謝您的回答。我現在明白了。謝謝,現在我的代碼對我更有意義。 – recursion1212

回答

1

您可以隨時鏈接函數,並鏈接到您想要的任何長鏈,直到函數返回對該對象的引用。當您撥打std::cout流上的超載operator <<時,會發生這種情況,這就是您可以在課堂上以相同方式編寫代碼的情況。

其基本思想是在課堂設計中。而不是在每個函數中返回void,而是返回對該對象的引用,該函數稱爲該函數。

class sample{ 
    sample& fun1(){cout << "fun1" << endl; return *this;}; 
    sample& fun2(int number){cout << "fun2("<<number<")\n"; return *this;}; 
    sample& fun3(){cout << "fun3" << endl; return *this;}; 
}; 

現在,你可以調用函數是這樣的:

sample yourObject; 
yourObject.fun1().fun2(5).fun3().fun1().fun2(12); 
1

這被稱爲生成器模式。

這不是某種特殊語言功能;相反,這些函數正在返回對它們被調用的對象的引用。

這些函數中的每一個函數的返回類型都是TypeId&,並且它們只返回*this,因此調用者可以在單個語句中鏈接許多函數。

3

這個技巧的關鍵是所有這些成員函數都返回對調用對象的引用。所以:

TypeId("Sender") 

這就調用構造函數,返回一個臨時對象。然後:

.SetParent<Application>() 

調用臨時TypeId對象的SetParent<>成員函數。它可能有這樣的簽名:

template<typename T> 
TypeId & SetParent(); 

所以,它返回到它被調用的對象(*this),這使得下一次調用,以AddConstructor<Sender>()的引用,該功能可能也有類似的簽名,鏈中的其他功能也一樣。

0

這是完全可能的鏈功能:

//foo() returns string 
auto size = foo().length(); 

這些功能可以被鏈接,如果他們各自返回&TypeId*this)類型:只是簡寫。

1

你所看到的是一種被稱爲builder pattern的設計模式。

每個設置某些內部狀態的方法都會改變某個內部狀態,然後返回對*this的引用,從而允許對同一對象進行進一步的調用。

最後,在概念上,我們存儲最後一次調用AddTraceSourcetid中返回的對象。由於所有前面的函數都返回了對同一個實例的引用,因此我們將存儲與構造函數最初創建的實例相同的實例。

因此,SetParent可能是大意如下

template <typename T> 
TypeId& TypeId::SetParent() 
{ 
    this->parent = T(); 
    return *this; 
} 

你可能已經遇到了在其他地方這種模式,以及實現。 Iostreams也可以使用它們的<<>>運營商。

std::cout << "Here's one call to the overloaded operator." 
      << " Here's another." 
      << " Take a look at the signature of operator<< when you get chance." 
      << std::endl;