NSFX手册的学习(7)

聚合

在组合中,对一个接口虚拟的调用被委托给了内部的组件。它的代价是对两个虚拟函数的调用。如果组合的层次再多一些,那么代价会成比例的增加。

如果外部的组件仅仅想要拥有内部组件那样的接口,通过减少接口的询问代价,聚合能够被用于减少虚拟调用的数量。

下面的例子显示了如和对一个组件进行聚合:

// aggregation.h
#include "config.h"
#include "nameable/i-nameable.h"

class Aggregation :
    virtual public IObject // Do not implement INameable directly.
{
public:
    Aggregation(void);
    virtual ~Aggregation(void);

private:
    NSFX_INTERFACE_MAP_BEGIN(Aggregation)
        // Provide an interface via aggregation.
        // The second argument MUST be the IObject* interface
        // exposed by the aggregated component.
        NSFX_INTERFACE_AGGREGATED_ENTRY(INameable, &*nameableObj_)
    NSFX_INTERFACE_MAP_END()

private:
    // The IObject interface of the aggregated component is stored.
    Ptr<IObject> nameableObj_;
};

NSFX_REGISTER_CLASS(Aggregation, "edu.uestc.nsfx.tutorial.Aggregation");
聚合不会使用INameable本身。因此,它并不由接口继承而来,它直接由IObject继承而来。
在接口地图中,宏NSFX_INTERFACE_AGGREGATED_ENTRY()提供的是聚合组件的接口。第二个声明一定是聚合组件使用的IObject接口。
聚合在构造器中制造了聚合的组件。例如:
// aggregation.cpp
#include "config.h"
#include "aggregation.h"

Aggregation::Aggregation(void) :
    // This component is the controller of the aggregated component.
    nameableObj_(CreateObject<IObject>("edu.uestc.nsfx.tutorial.Nameable",
                                       /* controller = */this))
{
    // The implementation of IObject on the aggregate component depends upon
    // the implemenation of IObject on its controller.
    // However, IObject on this component has not been implemented yet.
    //
    // Thus, neither query interface, nor modify the reference counter of
    // the aggregated component in the contructor.
}
CreateObject()由第二个声明提供,换句话说,它由Aggregation的this指针指出。它也被称之为聚合组件的控制器。
一个组件的所有接口一定要共享同一个生命期。这些接口都能互相询问。因此,由聚合组件应用的接口一定要能够管理控制器的参考计数器,同时可以询问控制器的接口。

猜你喜欢

转载自www.cnblogs.com/lx61/p/12188938.html
今日推荐