⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oopc.html

📁 c语言是面向过程的程序语言
💻 HTML
📖 第 1 页 / 共 5 页
字号:
can directly be used everywhere an <tt>object1</tt> is expected. But toguarantee the invariance of data alignment through inheritance, objectdata members must be encapsulated into a structure. Obviously, the presenceof the constant <tt>__vptr</tt> pointer, which may point to different <tt>vtbl</tt>,inside the structure forbids bitwise-copy of objects which must be performedmember by member. The same technique is used to build virtual table of<tt>object2</tt>but the encapsulation is not required since all slots have the same size(i.e. function pointers). RTTI structures are simply chained. Here followsthe equivalent model representation:<br>&nbsp;<center><table BORDER WIDTH="100%" NOSAVE ><caption><b>Object Model: Single inheritance</b></caption><tr NOSAVE><td ALIGN=LEFT VALIGN=TOP NOWRAP BGCOLOR="#99FFCC" NOSAVE><tt>object2&nbsp;&nbsp;&nbsp;(*)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vtbl2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type_info2 (1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type_info1 (1)</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +----------+</tt><br><tt>|&nbsp;&nbsp; __vptr | ---+-> |&nbsp;&nbsp; __info | -----> |&nbsp;&nbsp;__name |&nbsp;&nbsp;&nbsp; +-> |&nbsp;&nbsp; __name |</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; | __offset |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp; __class | ---+&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...|</tt><br><tt>|[data1]&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; +----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp; __super |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</tt><br><tt>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp; |[methods1]|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;__extra |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | __offset |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</tt><br><tt>|[data2]&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; +----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +----------+</tt><br><tt>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp; |[methods2]|</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</tt><br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp; +----------+</tt><br><tt>class2&nbsp;&nbsp;&nbsp;&nbsp; (1)&nbsp; |</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp; |</tt><br><tt>|&nbsp;&nbsp; __vptr | ---+</tt><br><tt>|&nbsp;&nbsp; ctor() |</tt><br><tt>|&nbsp;&nbsp; dtor() |</tt><br><tt>|&nbsp;&nbsp; ator() |</tt><br><tt>+----------+</tt><br><tt>|[methods] |</tt><br><tt>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</tt><br><tt>+----------+</tt></td></tr></table></center><p><b>Object Model and Multiple Inheritance</b><p>The principle used for multiple inheritance is the aggregation of objects,that means if <tt>object3</tt> inherits from <tt>object2</tt> and <tt>object1</tt>,the data of <tt>object1</tt> are at the begining of <tt>object3</tt>, followedby the data of <tt>object2</tt> including its <tt>__vptr</tt> pointer.Therefore an <tt>object3</tt> can directly be used everywhere an <tt>object1</tt>is expected, like for single inheritance, but it can also be used everywherean <tt>object2</tt> is expected after a small offset adjustment to the<tt>object2</tt>address inside the <tt>object3</tt>. Since <tt>object2</tt> is definedas an encapsulated member of <tt>object3</tt>, it is very easy to knowits offset and <tt>&amp;object3->object2</tt> tells to the compiler todo this offset ajustment. Here follows the equivalent model representation:<br>&nbsp;<center><table BORDER WIDTH="100%" NOSAVE ><caption><b>Object Model: Multiple inheritance</b></caption><tr ALIGN=LEFT VALIGN=TOP NOSAVE><td ALIGN=LEFT VALIGN=TOP NOWRAP BGCOLOR="#99FFCC" NOSAVE><tt>object3&nbsp;&nbsp;&nbsp;(*)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; vtbl3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type_info3 (1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type_info1 (1)</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +----------+</tt><br><tt>|&nbsp;&nbsp; __vptr | ---+-> |&nbsp;&nbsp; __info | -----> |&nbsp;&nbsp;__name |&nbsp;&nbsp;&nbsp; +-> |&nbsp;&nbsp; __name |</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; | __offset |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp; __class | ---+&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...|</tt><br><tt>|[data1]&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; +----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp; __super |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</tt><br><tt>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp; |[methods1]|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;__extra |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | __offset |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</tt><br><tt>|&nbsp; __vptr2 | -+ |&nbsp;&nbsp; +----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +----------+</tt><br><tt>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---+&nbsp; +---> |&nbsp;__info2 | --+</tt><br><tt>|[data2]&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; |__offset2|&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; type_info2 (1)</tt><br><tt>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---+&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;+----------+</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; |[methods2]|&nbsp;&nbsp;+--> |&nbsp;&nbsp; __name |</tt><br><tt>|[data3]&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;... |</tt><br><tt>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp; +----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp; |[methods3]|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</tt><br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</tt><br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp; +----------+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +----------+</tt><br><tt>class3&nbsp;&nbsp;&nbsp;&nbsp; (1)&nbsp; |</tt><br><tt>+----------+&nbsp;&nbsp;&nbsp; |</tt><br><tt>|&nbsp;&nbsp; __vptr | ---+</tt><br><tt>|&nbsp;&nbsp; ctor() |</tt><br><tt>|&nbsp;&nbsp; dtor() |</tt><br><tt>|&nbsp;&nbsp; ator() |</tt><br><tt>+----------+</tt><br><tt>|[methods] |</tt><br><tt>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</tt><br><tt>+----------+</tt></td></tr></table></center><p>The RTTI of <tt>object3</tt> and <tt>object1</tt> are chained, but theRTTI of <tt>object2</tt> remains separate since <tt>object2</tt> inside<tt>object3</tt>must behave exactly as a true <tt>object2</tt>. In fact, the only differencebetween a true <tt>object2</tt> and the <tt>object2</tt> inside <tt>object3</tt>is the value of the field <tt>__offset2</tt> in the virtual table whichholds the offset of <tt>object2</tt> inside <tt>object3</tt>. A true <tt>object2__vptr</tt>would point to the virtual table of <tt>object2</tt> and not inside thevirtual table of <tt>object3</tt> and therefore the<tt>__offset</tt> fieldvalue would be zero.<p>&nbsp;For more information about the <i>OOPC Object Model</i>, see thepseudo C file <tt><a href="objectModel.c">objectModel.c</a></tt>.<br>&nbsp;<table CELLPADDING=5 COLS=1 WIDTH="100%" BGCOLOR="#66FFFF" NOSAVE ><tr NOSAVE><td NOSAVE><a NAME="Object"></a><b><font face="Arial,Helvetica"><font size=+2>Object</font></font></b></td></tr></table><p>Assuming that a person may be identified by its name, this informationshould be encapsulated into an <i>object</i> to reflect the ownership ofthese data by the person. A typical approach would be:<blockquote><tt>struct t_person {</tt><br><tt>&nbsp; char *name;</tt><br><tt>};</tt></blockquote>In fact, objects and classes in OOPC are always defined as aggregations(structures or unions). It answers to the second constraint: the name encapsulation.OOPC macros achieve simply the object definition which in reality lookslike:<blockquote><tt>typedef union {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* generated */</tt><br><tt>&nbsp; struct _ooc_vtbl_person const*const <b>__vptr</b>; /* generated*/</tt><br><tt>&nbsp; struct _ooc_vtbl_object const*const <b>__iptr</b>; /* generated*/</tt><br><tt>&nbsp; struct {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* generated */</tt><br><tt>&nbsp;&nbsp;&nbsp; <b>t_object</b> const <b>private</b>(_);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* generated */</tt><br><tt>&nbsp;&nbsp;&nbsp; char const* <b>private</b>(name);</tt><br><tt>&nbsp; } <b>m</b>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* generated */</tt><br><tt>} t_person;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* generated */</tt></blockquote>From this definition, which is exactly what OOPC does, we can do the followingremarks:<ul><li>All <i>objects type</i> have a <tt>t_</tt> concatenated in front of its(class) name to specify that is an object/a type (i.e. <tt>t_person</tt>).</li><li>All <i>objects</i> begin with a hidden member constant pointer <tt>__vptr</tt>to their <i>virtual table</i> (i.e. hidden type <tt>struct _ooc_vtbl_person</tt>).</li><li>All <i>objects</i> begin with a hidden member constant pointer <tt>__iptr</tt>to their <i>virtual table information</i> part (i.e. hidden type <tt>struct_ooc_vtbl_object</tt>).</li><li>All <i>objects</i> always inherit from the base object <tt>t_object</tt>(i.e. <tt>t_object const private(_)</tt>) or from another object.</li><li>All <i>objects</i> have their data encapsulated into the <tt>m</tt> structurethrough which you can access objects members (i.e. <tt>obj->m.name</tt>).</li><li>All <i>objects instances</i> have a size equal to sizeof <tt>m</tt> = sizeof<tt>__vptr</tt>+ sizeof data + data alignment.</li></ul>The object designer should never take care about the encapsulation of itsdata whose purpose is only to reflect the <i>Object Model</i> structureand guarantee the data alignment invariance through inheritance, and insteadhe should use the OOPC object interface (see <tt><a href="examples/person.h">person.h</a></tt>for a complete interface):<blockquote><tt>#define <b>OBJECT</b> person</tt><p><b><tt>BASEOBJECT_INTERFACE</tt></b><p><tt>&nbsp; char const* <b>private</b>(name);&nbsp; /* object member*/</tt><p><b><tt>BASEOBJECT_METHODS</tt></b><p><tt>&nbsp; void <b>constMethod</b>(print);&nbsp;&nbsp;&nbsp; /* objectmethod */</tt><p><b><tt>ENDOF_INTERFACE</tt></b></blockquote>The <tt>private()</tt> macro transforms the token of the field<tt>name</tt>into something which is unreachable outside from the class implementation(C++: private). The <tt>public()</tt> macro is also available to definepublic (reachable) fields (C++: public). In the <tt>BASEOBJECT_METHODS</tt>section, the object method (message) <tt>print</tt> is defined as a <i>constantobject method</i> (C++: constant virtual member function) using the<tt>constMethod()</tt>macro, that means it does not modify the <tt>this</tt> pointer. The <tt>method()</tt>macro is also available to define non-constant object methods. Note thatthe class person does not derive from any other class and therefore isdefined as a <i>base object</i>.<p>Declaring an object instance, a pointer to an object instance, a constantpointer to an object instance and a constant pointer to a constant objectinstance can be done as in C++:<ul><tt>t_person obj_auto;</tt><br><tt>t_person *obj_ptr;</tt><br><tt>t_person *const obj_const_ptr;</tt><br><tt>t_person const*const const_obj_const_ptr;</tt></ul>Of course, the variables need to be properly initialized before being used.Usually, the third declaration is used since most of the OOPC macros waitfor an object pointer and declaring the pointer as constant protects itagainst a misassignment.<br>&nbsp;<table CELLPADDING=5 COLS=1 WIDTH="100%" BGCOLOR="#66FFFF" NOSAVE ><tr NOSAVE><td NOSAVE><a NAME="Class"></a><b><font face="Arial,Helvetica"><font size=+2>Class</font></font></b></td></tr></table><p>Classes collect and encapsulate the following information:<ul><li><i>Static data</i>: data with one instance per class (C++: static member).</li><li><i>Class methods</i>: non-polymorphic methods without the <tt>this</tt>pointer (C++: static member function).</li><li><i>Methods</i>: non-polymorphic methods with the <tt>this</tt> pointer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -