65.9K
CodeProject 正在变化。 阅读更多。
Home

C++ 元类

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.60/5 (4投票s)

1999年12月1日

2分钟阅读

viewsIcon

77638

downloadIcon

1044

可在运行时修改的类

引言

这是一个用 C++ 实现的简单元类仿真。元类是一个类的类,即这个类的对象本身可以充当类。因此,用户可以在运行时添加或删除属性。

我正在进行的一个项目需要一个类似于这个类的功能。首先,我们设计一个类(例如具有 x、y 和 z 属性),供用户使用。但是,非常进取的用户希望向这个类添加更多数据供他/她和其他人使用。因此,他添加了属性 a 和 b 到这个类,现在它具有 x、y、z、a 和 b 作为其属性。这个用户所做的新增内容将仅供他使用,除非他或管理员授予其他有要求的用户的权限。该类的管理员有权向其添加属性,因此使用静态函数。

所以即使类是相同的,它的可见性对于不同的用户和应用程序也是不同的。因此它可以用于不同的用途。在我编写的类中,仅使用了一个 TCHAR。用户可以使用列表,或者根据他/她的需要使用任何东西。

因此,该类适用于用户应该能够在运行时添加新属性的地方;-- 一个用户定义的类,但在运行时。

C++ 本身并不直接支持这种机制,就像 Smalltalk 和 CLOS 中一样。但是,它可以使用其静态数据和函数成员在 C++ 中实现。

此程序实现了一个名为 MetaVec 的元类。MetaVec 的静态数据和函数在其实例化之前就存在。因此,可以从“外部”向其添加一个属性,在本例中是一个字符串数组。

添加到这个类的属性对它的所有成员都可用。其想法是限制对这个类的对象访问这些属性。此权限是通过为每个对象分配特定的索引来指定的。这些索引对应于链表 PtrVec 中的值(属性)。例如,如果列表有 7 个名称,并且对象 A 仅被分配了索引 0、1 和 3,那么它只能访问链表中位于这些索引位置的那些名称。

因此,这个类的许多对象都可以拥有不同的属性;一种用户定义的类,在运行时。

这个元类的演示版本使用字符串值作为属性。用户可以使用链表作为静态容器对象。PtrVec 是一个 STL 模板,可以包含任何类型的对象。

// MetaVec class definition

typedef vectorPtrVec; // container object
typedef PtrVec::iterator itPtrVec;

typedef vectorListIndex;
typedef ListIndex::iterator itListIndex;


typedef long INDEX;
typedef long ATTRIBUTE_NO;
typedef long NO_OF_ATTRIBUTES;
typedef ListIndex LIST_INDEX;


class MetaVec
{
private:
    // identifer of this object
    int iClsID;
    // total count of classes for assigining ClsIDs automatically
    static int ClsCount;
    // list of indices for attributes
    // that are permitted fot this object
    ListIndex Index;
    // for locking the object. New attributes
    // can be added but cannot be used
    bool ObjectLock;

    // list of attributes for the metaclass ie all objects
    static PtrVec VecObject;

public:
    MetaVec(bool LockStatus = false);
    ~MetaVec();

    // Adds a new attributes to the metaclass - in the list of names
    static long AddAttribute(TCHAR* Name);

    // This assignes an index to an object
    // to decide the permissions that object has on
    // the attributes of the metaclass. Any object can
    // access only those attributes that 
    // are assigned to it
    bool AssignIndex(ListIndex LstIndex);

    // overloaded to receive a single value
    bool AssignIndex(int iIndex);

    // removes the assigned index and
    // returns the removed index -- overloaded
    INDEX RevokeIndex(int iIndex);

    // removes a list of assigned indexes and returns the removed list
    LIST_INDEX RevokeIndex(ListIndex IndexList);

    // this lists all the available attributes and their IDs
    static NO_OF_ATTRIBUTES ListAllAttributes();

    // Queries an object for its properties - Class ID, Index and Name
    void QueryObject();

    // locks the object so that no new indices can be assigned to it
    // toggles between locked and un-locked
    bool LockObject(bool LockState = true);

    // checking the lock status of an object
    bool CheckLockStatus();
};
© . All rights reserved.