Metaclasses and Reflection in C++
2012-03-05 12:53
459 查看
Introduction
C++ is a strongly typed compiler language. Though not as strongly typed as ADA, a C++ compiler will complain if you try to assign an object of one type to an object of another type (if there is no acceptable conversion). Obviously, this requires that the compiler knows all available types. More specifically, all classes must be known at compile-time1. But sometimes, it would be quite handy to add new classes at runtime. And in some application domains, this is absolutely necessary.A simple story
Let's look at a simple example: Susan, the manager of a local bookstore, wants to expand into the Internet. So she asks you to write a simple program for an Internet bookshop. No problem for you. Part of your solution will probably look like the class model in Fig. 1.Object Class
class Object { public: explicit Object(ClassDef const * class_) : myClass(class_), values(class_->getAttributeCount()) { buildValueList(); } ClassDef const & instanceOf() const { return *myClass; } Value getValue(size_t attribIdx) const { return *values[attribIdx]; // calls Value(BaseValue &) } Value getValue(string const & attribName) const { size_t idx = instanceOf()->findAttribute(attribName); // should check for not found return getValue(idx); } void setValue(size_t idx, Value const & v) { values[idx]->set(v); } void setValue(string const & attribName, Value const &v) { size_t idx = instanceOf()->findAttribute(attribName); // should check for not found setValue(idx, v); } private: typedef vector<BaseValue *> ValueContainer; void buildValueList() { ClassDef::AttrIterator a; ValueContainer::iterator i = values.begin(); for (a = instanceOf()->attribBegin(); a != instanceOf()->attribEnd(); ++a, ++i) { *i = a->getType().newValue(); } } ClassDef const * const myClass; ValueContainer values; };
Now the MOP is complete. Let's use it:
Creating the
Productclass:
ClassDef * product = new ClassDef(0, // no base class for Product "Product"); // name of class
Adding attributes:
product->addAttribute(Attribute("Product Number", Type::intT)); product->addAttribute(Attribute("Name", Type::stringT)); product->addAttribute(Attribute("Price", Type::doubleT)); product->addAttribute(Attribute("Weight", Type::doubleT));
Creating the
Bookclass with an attribute list:
list<Attribute> attrL; attrL.push_back(Attribute("Author", Type::stringT)); attrL.push_back(Attribute("Title", Type::stringT)); attrL.push_back(Attribute("ISBN", Type::intT)); ClassDef * book = new ClassDef(product, // base class "Book", attrL.begin(), attrL.end());
Creating an object:
Object * bscpp(book->newObject());
Setting the values for the objects:
Set an int value by index (don't forget that index 0 isProductNo):
bscpp->setValue(0, RealValue<int>(12345));
Same for a string value:
bscpp->setValue(4, RealValue<string>("Bjarne Stroustrup"));
Better way: set value by name this gives the most derived attribute:
bscpp->setValue("Title", RealValue<string>("The C++ Programming Language")); bscpp->setValue("Weight", Value<double>(370));
Getting the values:
Display a book:ClassDef::AttrIterator a; size_t idx; for (a = book->attribBegin(), idx = 0; a != book->attribEnd(); ++a, ++idx) { cout << a->getName() << ": " << bscpp->getValue(idx).asString() << endl; }
and we get:
Product Number: 12345 Name: Price: Weight: 370 Author: Bjarne Stroustrup Title: The C++ Programming Language ISBN:
So, our MOP is complete. For our sample application, you have to add a class repository, some nice GUI to define classes and objects, creating the index for the search machine, provide an interface for
ShoppingCart, but then you're done, and Susan is happy as she now can create her own new product categories at runtime.
相关文章推荐
- 【转】How to call c++ exported method and classes in c#
- Pure Virtual Functions and Abstract Classes in C++
- Using dllimport and dllexport in C++ Classes
- How to call c++ exported method and classes in c#
- result of += in C and C++
- RAII, Dynamic Objects, and Factories in C++
- 《Data Structure And Algorithm Analysis In C++》读书笔记四
- zz : A LNK2005 error occurs when the CRT library and MFC libraries are linked in the wrong order in Visual C++ ---- nafxcw.lib(a
- [C++]LeetCode: 38 Construct Binary Tree from Inorder and Postorder Traversal
- Using SiteMap and MasterPages to set META Tags in ASP.NET and C#
- Object layout in C++ and access control
- best strategies for implementation of equals() and hashcode() in your persistent classes
- C++ template funcitons and classes
- An Introduction to Reflection in C++
- 第十四节--命名空间 -- Classes and Objects in PHP5 [14](转)
- char, signed char, and unsigned char in C++
- 第十四节--命名空间 -- Classes and Objects in PHP5 [14]
- C++ Find Min and Max element in a BST
- 【c++】PAT (Advanced Level) 1006. Sign In and Sign Out (25)
- Reversing Microsoft Visual C++ Part II: Classes, Methods and RTTI