我不知道这可以用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 :(得分:3)
这个技巧的关键是所有这些成员函数都返回对调用对象的引用。所以:
TypeId("Sender")
调用构造函数,返回一个临时对象。然后:
.SetParent<Application>()
调用临时SetParent<>
对象的TypeId
成员函数。它可能有这样的签名:
template<typename T>
TypeId & SetParent();
因此,它返回对调用它的对象(*this
)的引用,该对象允许下一次调用AddConstructor<Sender>()
,并且该函数可能具有类似的签名,链中的其他功能。
答案 1 :(得分:1)
您可以随时链接函数和所需的长链,直到函数返回对象的引用。当您在operator <<
流上调用重载的std::cout
时会发生这种情况,这也是您可以在课堂上以相同的方式编写代码的方式。
基本理念是在课堂设计中。而不是在每个函数中返回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);
答案 2 :(得分:1)
这称为构建器模式。
这不是某种特殊语言功能;相反,函数返回对它们被调用的对象的引用。
这些函数中的每一个都具有返回类型TypeId&
,并且它们只是返回*this
,因此调用者可以在一个语句中将许多函数链接在一起。
答案 3 :(得分:1)
您所看到的是一种称为builder pattern的设计模式。
设置内容的每个方法都会改变一些内部状态,然后返回对*this
的引用,允许对同一个对象进行进一步的调用。
最后,从概念上讲,我们将最后一次调用AddTraceSource
返回的对象存储在tid
中。由于前面的所有函数都返回了对同一实例的引用,因此我们将存储构造函数最初创建的相同实例。
因此,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;
答案 4 :(得分:0)
完全可以链接功能:
//foo() returns string
auto size = foo().length();
如果每个函数都返回&TypeId
(*this
)类型,则可以链接这些函数:只是简写。