2013-11-15 51 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;