2

I didnt know this was possible to do in C++, until I saw it. AddAttribute(),AddTraceSource(),etc are member functions of the class 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;
}

I never knew we could do this in C++. Could someone please throw more light on this topic (calling multiple member functions during object creation)? I know we can do this in scripting. But in c++? The file had an extension *.cc. Sorry if my question is naive, and it turns out I missed out on reading a few chapters in C++?!

4

5 回答 5

3

这个技巧的关键是所有这些成员函数都返回对调用对象的引用。所以:

TypeId("Sender")

调用构造函数,返回一个临时对象。然后:

.SetParent<Application>()

那调用临时对象的SetParent<>成员函数。TypeId它可能有这样的签名:

template<typename T>
TypeId & SetParent();

因此,它返回对调用它的对象的引用 ( *this),这允许下一次调用 to AddConstructor<Sender>(),并且该函数可能具有类似的签名,就像链中的其他函数一样。

于 2013-11-15T02:07:30.763 回答
1

What you're seeing is a design pattern known as the builder pattern.

Each of the methods that set something mutates some internal state and then returns a reference to *this, allowing further calls to be made on the same object.

Finally and conceptually, we store the object returned by the last call, AddTraceSource, in tid. Since all the preceding functions returned a reference to the same instance, we'll store the same instance that the constructor created initially.

Thus, SetParent is probably implemented along the following lines

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

You've probably encountered this pattern in other places as well. Iostreams do this as well with their << and >> operators.

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;
于 2013-11-15T02:14:31.080 回答
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);
于 2013-11-15T02:05:08.953 回答
1

这被称为建造者模式。

这不是某种特殊的语言功能。相反,这些函数正在返回对它们被调用的对象的引用。

这些函数中的每一个都有一个返回类型TypeId&,它们只是返回*this,所以调用者可以在一条语句中将许多函数链接在一起。

于 2013-11-15T02:07:09.027 回答
0

完全可以链接功能:

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

如果这些函数都返回一个&TypeId( *this) 类型,则可以将它们链接起来:只是简写。

于 2013-11-15T02:07:55.830 回答