The following is a re-post of something from the old board. However, since it was burried down at the 19th post of the thread (and never had an replies) I thought I'd paste it up here so smeone might atually benefit from it. Dang, I got the friggin POSTNAME wrong, it should be "OOP in MASM," not "OOP is MASM" Re OOP in MASM: Having been there, done that, AND got the T-shirt... Low level object programming in MASM is quit possible, doable, lightweight, and practicable. How you implement it is, of course, your choice. But certain guidelines should be upheld. An object is basically run-time allocated memory. The basis behind all of OOP is sending the method code a reference to the object being worked with. This reference is typically called "THIS" THIS is the address of some part of the object, so THIS can be used to reference any part of the structure. And by imposing the THIS to point to the implementation method pointer (or virtual) table gives us a simple way of implementing dynamic casting (more on this later). As a minimum, any OOP implementation will need 3 functions: CreateObject, DestroyObject, and DynamicCast. It's often heard a CLASS defines the OBJECT. In practical terms, a CLASS is a set of definitions of how the object should be built. It is just a structure, it contains the values that define in some way, what the object will be. The CreateObject method takes a pointer to a class definition structure, and creates an object to this model. Should special object initialization be needed, the CLASS may be defined with a pointer to a custom initialization method. The CLASS may also contain a custom release method for DestroyObject to use so it may clean up after itself. DynamicCast can give you fits until it gels in your mind. It comes about because there are two types of inheritance possible: single (or direct) and multiple. Single inheritance implements the "is-a" relationship. Multiple inheritance implements the "has-a" relationship. They work like so: Class Joe{ISA Man} Class Man {ISA Human} Class Human{ISA Mammal} This defines a single inheritance model for Joe. However, is we want Joe to be able to wave his hand and walk and talk, we need something else like: Class Joe{IS_A Man} Class Man {IS_A Human} Class Human{HAS_A Mouth, HAS_A RHand, HAS_A LHand, HAS_A LFoot, HAS_A RFoot} Class RFoot {IS_A Foot} Class LFoot {IS_A Foot} and so on. The point being, if we have a reference to Joe, we need some way to find his foot to get him moving! Somehow his object must contain all these other details. That is why you need THIS to point to the object, and then on to the function table. You will need to change the numeric value of THIS if your class needs a dynamic cast. THIS points to one member of a table of pointers, each pointing to a different implementation table. A picture here would sure help. See my "Inside CoLib" for "CASTING AN OBJECT FOR AN INTERFACE" at I will admit my CLASS models take a few shortcuts: only the bottom level (most derived) CLASS may have data members, and the function tables must be assigned directly (this is mostly due to the 500 characters per line limit of MASM when defining structures). Macros handle class member definitions such that the interface inheritance is realized, which is far more important to easy coding then having the function pointer table filled in for you (which you would have to implement by getting the proc names the same anyway). How much overhead does it all bring? The gross line count for these routines, heavily commented, with compile directives to make an object library is thus: CreateObject 174 lines DestroyObject 54 lines DynamicCast 133 lines Objects are: 4 x (7 + (data members in dwords) + 2 x (interface count + 1) ) bytes IE, a direct CLASS (no inheritance), with 1 DWORD of data would be 40 bytes. Finally, objects are just necessary. The Windows OS will continuously increase it's reliance on Common Object Model techniques, and those who refuse to learn th
Posted on 2001-01-31 13:41:00 by Ernie