The C++ Object Model: Good? Bad? Ugly? : c++
This is a discussion on The C++ Object Model: Good? Bad? Ugly? within the c++ forums in Programming Languages category; On Nov 3, 11:55 pm, tonytech08 <tonytec...@gmail.com> wrote: > On Nov 3, 4:25 pm, James Kanze <james.ka...@gmail.com> wrote: > > On Nov 3, 8:44 pm, tonytech08 <tonytec...@gmail.com> wrote: > > > On Nov 1, 3:32 am, James Kanze <james.ka...@gmail.com> wrote: > > > > On Nov 1, 4:02 am, tonytech08 <tonytec...@gmail.com> wrote: > > > > > What I like about the C++ object model: that the data > > > > > portion of the class IS the object (dereferencing an > > > > > object gets you the data of a POD object). > > > > ...
| c++ comp.lang.c++ usenet archive |
![]() |
| | LinkBack | Thread Tools |
|
#11
| |||
| |||
| > On Nov 3, 4:25 pm, James Kanze <james.ka...@gmail.com> wrote: > > On Nov 3, 8:44 pm, tonytech08 <tonytec...@gmail.com> wrote: > > > On Nov 1, 3:32 am, James Kanze <james.ka...@gmail.com> wrote: > > > > On Nov 1, 4:02 am, tonytech08 <tonytec...@gmail.com> wrote: > > > > > What I like about the C++ object model: that the data > > > > > portion of the class IS the object (dereferencing an > > > > > object gets you the data of a POD object). > > > > No it doesn't. > > > class SomePODClass > > > { > > > public: > > > int first_int; > > > int second_int; > > > void Func1(){} > > > }; > > > SomePODClass X; > > > int first_int_in_obj = *(int*)&X; // this is not pretty, but true > > But it's only true for POD types, > Well that's why I added the parenthetical part in my original > post: to make clear I was referring to what I like about the > C++ model and wish it wouldn't get abberated so quickly by > changing the memory representation of the data portion. 'POD' > was very key for my thought, though could have been worded > better to show that I guess. Well, PODs make up part of the C++ object model; one important aspect of it is that PODs do behave differently from objects which have non-trivial constructors or destructors. The main reasons for this are probably linked with C compatibility, but it was always intended in C++ that you could create simple structures which were no more than a collection of data (with or without member functions), as well as full OO type objects. The object model of C++ is designed to support both. > > and only because of constraints of C compatiblity. The data > > portion of the class isn't the object in general. > I tend to think of the data portion (noun, vs. behavior=verb) > as "the thing" because that's what get's operated on and maybe > even directly manipulated. In C++ (and even in C, for that matter), an object has a type and an address; the type determines its size, and the set of legal operations on it. Since an object is a thing, in some way, I guess it is a noun, but even a POD struct has behavior: you can assign it, for example, or access members. Compared to C, C++ adds the ability for the user to define additional operations (member functions), and to define non-trivial initialization and destruction (which forces significant changes in the object model). Beyond that, C++ adds support for dynamic typing (which is what one usually understands with OO). [...] > > It restricts the use of OO concepts to classes designed to > > be used with OO concepts. > Not really, since one can have POD classes with methods, just > not CERTAIN methods (you are suggesting that "classes designed > to be used with OO concepts" are those heavyweight classes > that break PODness, right?). No. I'm really not suggesting much of anything. However you define the concept of OO, the concept only applies to classes which were designed with it in mind. C++ doesn't force any particular OO model, but allows you to chose. And to have classes which aren't conform to this model. > You seem to be saying that POD classes are not supported or at > least not encouraged. Where do I say that? POD classes are definitely supported, and are very useful in certain contexts. They aren't appropriate for what most people would understand by OO, but so what. Not everything has to be rigorously OO. > That would be a real downer if true. I'd like to see more > support in the langauge for POD classes. Such as? Part of the motivation for defining POD as a special category is C compatibility; a POD should be usable in C. Beyond that, there is a wide range of things you can do. > I don't know how much can be implemented before it becomes > impossible. Certainly initializing constructors can be had? A non-trivial constructor causes changes in the way object lifetime is defined. So the results aren't (and can't be) a POD. The justification is simple: you can't define an object with a non-trivial constructor in C. > Polymorphism not, but only NOT because of the way C++ > implements it? Polymorphism implies a non-trivial constructor. Regardless of how it is implemented, something must occur (some code must execute) for the raw memory to assume its type. The next version of the standard adds some additional definitions; in addition to PODs and agglomerates, it has something called standard-layout structs and unions, and support for managing alignment. But even without that, I've found plenty of support for everything I've had to do, at all levels. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
#12
| |||
| |||
| On Nov 4, 5:51 am, Ian Collins <ian-n...@hotmail.com> wrote: [...] > An instance of a polymorphic class has to contain information > about its type, so it can't be the same as a POD class. > Constructors and (non-virtual) methods are irrelevant. Just a nit, but it's possible to implement polymorphism with no additional information in the instance itself; you could, for example, maintain the information is a separate hashtable which mapped the address to the type information. What isn't possible is to establish this mapping without executing some code. I.e. a constructor. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
#13
| |||
| |||
| On Nov 3, 10:51 pm, Ian Collins <ian-n...@hotmail.com> wrote: > tonytech08 wrote: > > On Nov 3, 4:25 pm, James Kanze <james.ka...@gmail.com> wrote: > >> It restricts the use of OO concepts to classes designed to be > >> used with OO concepts. > > > Not really, since one can have POD classes with methods, just not > > CERTAIN methods (you are suggesting that "classes designed to be used > > with OO concepts" are those heavyweight classes that break PODness, > > right?). > > What's a "heavyweight class"? A non-POD class. > > > You seem to be saying that POD classes are not supported or > > at least not encouraged. > > Where? They are supported, a C struct is also a C++ struct. "Not supported adequately" is what I meant. > > > That would be a real downer if true. I'd like > > to see more support in the langauge for POD classes. I don't know how > > much can be implemented before it becomes impossible. Certainly > > initializing constructors can be had? Polymorphism not, but only NOT > > because of the way C++ implements it? > > An instance of a polymorphic class has to contain information about its > type, so it can't be the same as a POD class. Because of the way C++ implements polymorphism: tacking on a vptr to the class data. > Constructors and > (non-virtual) methods are irrelevant. Apparently relevant: a POD can't have "non-trivial" constructors, for one thing. |
|
#14
| |||
| |||
| On Nov 4, 3:06 am, James Kanze <james.ka...@gmail.com> wrote: > On Nov 3, 11:55 pm, tonytech08 <tonytec...@gmail.com> wrote: > > > > > > > On Nov 3, 4:25 pm, James Kanze <james.ka...@gmail.com> wrote: > > > On Nov 3, 8:44 pm, tonytech08 <tonytec...@gmail.com> wrote: > > > > On Nov 1, 3:32 am, James Kanze <james.ka...@gmail.com> wrote: > > > > > On Nov 1, 4:02 am, tonytech08 <tonytec...@gmail.com> wrote: > > > > > > What I like about the C++ object model: that the data > > > > > > portion of the class IS the object (dereferencing an > > > > > > object gets you the data of a POD object). > > > > > No it doesn't. > > > > class SomePODClass > > > > { > > > > public: > > > > int first_int; > > > > int second_int; > > > > void Func1(){} > > > > }; > > > > SomePODClass X; > > > > int first_int_in_obj = *(int*)&X; // this is not pretty, but true > > > But it's only true for POD types, > > Well that's why I added the parenthetical part in my original > > post: to make clear I was referring to what I like about the > > C++ model and wish it wouldn't get abberated so quickly by > > changing the memory representation of the data portion. 'POD' > > was very key for my thought, though could have been worded > > better to show that I guess. > > Well, PODs make up part of the C++ object model; one important > aspect of it is that PODs do behave differently from objects > which have non-trivial constructors or destructors. The main > reasons for this are probably linked with C compatibility, but > it was always intended in C++ that you could create simple > structures which were no more than a collection of data (with or > without member functions), as well as full OO type objects. The > object model of C++ is designed to support both. Thanks for reiterating my thought: C++ has more support for OO with "full OO type objects". > > > > and only because of constraints of C compatiblity. The data > > > portion of the class isn't the object in general. > > I tend to think of the data portion (noun, vs. behavior=verb) > > as "the thing" because that's what get's operated on and maybe > > even directly manipulated. > > In C++ (and even in C, for that matter), an object has a type > and an address; the type determines its size, and the set of > legal operations on it. Since an object is a thing, in some > way, I guess it is a noun, but even a POD struct has behavior: > you can assign it, for example, or access members. Compared to > C, C++ adds the ability for the user to define additional > operations (member functions), and to define non-trivial > initialization and destruction (which forces significant changes > in the object model). Beyond that, C++ adds support for dynamic > typing (which is what one usually understands with OO). Not sure what your point is. I said that I consider the data portion of an object, "the object". I wasn't trying to be implementation literal about it. Yes, data+behavior= class, but when the implementation starts adding things to the data portion, that defines a different animal than a POD class. > > [...] > > > > It restricts the use of OO concepts to classes designed to > > > be used with OO concepts. > > Not really, since one can have POD classes with methods, just > > not CERTAIN methods (you are suggesting that "classes designed > > to be used with OO concepts" are those heavyweight classes > > that break PODness, right?). > > No. I'm really not suggesting much of anything. However you > define the concept of OO, the concept only applies to classes > which were designed with it in mind. C++ doesn't force any > particular OO model, but allows you to chose. And to have > classes which aren't conform to this model. "Allows you to choose"? "FORCES you to choose" between lightweight (POD) class design with more limited OO and and heavyweight (non-POD) class design with all OO mechanisms allowed but at the expense of losing POD-ness. It's a compromise. I'm not saying it's a bad compromise, but I am wondering if so and what the alternative implementation possibilities are. > > > You seem to be saying that POD classes are not supported or at > > least not encouraged. > > Where do I say that? POD classes are definitely supported, and > are very useful in certain contexts. They aren't appropriate > for what most people would understand by OO, but so what. Not > everything has to be rigorously OO. You seemed to imply that the "supported" ("ecouraged" would probably be a better word to use) paradigms were: A. data structs with non- trivial member functions and built-in "behavior" and B. "full OO type objects". > > > That would be a real downer if true. I'd like to see more > > support in the langauge for POD classes. > > Such as? What I call "initializing constructors" for one thing. (Constructors that take arguments to initialize a POD class in various ways). > Part of the motivation for defining POD as a special > category is C compatibility; a POD should be usable in C. > Beyond that, there is a wide range of things you can do. Can't construct conveniently as you can with heavyweight class objects. Why allowing this would break POD-ness escapes me. Perhaps it would break C-compatibility? Maybe defining POD-ness as "C compatibility of structs" is a hindrance, if it is defined something like that. > > > I don't know how much can be implemented before it becomes > > impossible. Certainly initializing constructors can be had? > > A non-trivial constructor causes changes in the way object > lifetime is defined. So the results aren't (and can't be) a > POD. The justification is simple: you can't define an object > with a non-trivial constructor in C. So it is just the backward compatibility with C that prevents having those nifty constructors? > > > Polymorphism not, but only NOT because of the way C++ > > implements it? > > Polymorphism implies a non-trivial constructor. Regardless of > how it is implemented, something must occur (some code must > execute) for the raw memory to assume its type. The more obvious issue with the polymorphism implementation is the vptr. But I'm not too worried about not being able to derive from POD- classes (for now anyway). > > The next version of the standard adds some additional > definitions; in addition to PODs and agglomerates, it has > something called standard-layout structs and unions, and support > for managing alignment. But even without that, I've found > plenty of support for everything I've had to do, at all levels. |
|
#15
| |||
| |||
| On Nov 4, 3:08 am, James Kanze <james.ka...@gmail.com> wrote: > On Nov 4, 5:51 am, Ian Collins <ian-n...@hotmail.com> wrote: > > [...] > > > An instance of a polymorphic class has to contain information > > about its type, so it can't be the same as a POD class. > > Constructors and (non-virtual) methods are irrelevant. > > Just a nit, but it's possible to implement polymorphism with no > additional information in the instance itself; you could, for > example, maintain the information is a separate hashtable which > mapped the address to the type information. What isn't possible > is to establish this mapping without executing some code. I.e. a > constructor. And how relatively (relative to the current implementation) slow would that be is the question. I'm pretty much doing that for GUI code (windowing). I'm not sure that it's appriate at the language implementation level as a technique though (?). |
|
#16
| |||
| |||
| On Nov 3, 10:51 pm, Ian Collins <ian-n...@hotmail.com> wrote: > tonytech08 wrote: > > On Nov 3, 4:25 pm, James Kanze <james.ka...@gmail.com> wrote: > >> It restricts the use of OO concepts to classes designed to be > >> used with OO concepts. > > > Not really, since one can have POD classes with methods, just not > > CERTAIN methods (you are suggesting that "classes designed to be used > > with OO concepts" are those heavyweight classes that break PODness, > > right?). > > What's a "heavyweight class"? > > > You seem to be saying that POD classes are not supported or > > at least not encouraged. > > Where? They are supported, a C struct is also a C++ struct. "not encouraged" I should have said. |
|
#17
| |||
| |||
| tonytech08 wrote: > On Nov 3, 10:51 pm, Ian Collins <ian-n...@hotmail.com> wrote: >> tonytech08 wrote: >>> On Nov 3, 4:25 pm, James Kanze <james.ka...@gmail.com> wrote: >>>> It restricts the use of OO concepts to classes designed to be >>>> used with OO concepts. >>> Not really, since one can have POD classes with methods, just not >>> CERTAIN methods (you are suggesting that "classes designed to be used >>> with OO concepts" are those heavyweight classes that break PODness, >>> right?). >> What's a "heavyweight class"? >> >>> You seem to be saying that POD classes are not supported or >>> at least not encouraged. >> Where? They are supported, a C struct is also a C++ struct. > > "not encouraged" I should have said. By whom? -- Ian Collins |
|
#18
| |||
| |||
| On Nov 6, 11:36 pm, tonytech08 <tonytec...@gmail.com> wrote: > On Nov 4, 3:08 am, James Kanze <james.ka...@gmail.com> wrote: > > On Nov 4, 5:51 am, Ian Collins <ian-n...@hotmail.com> wrote: > > [...] > > > An instance of a polymorphic class has to contain > > > information about its type, so it can't be the same as a > > > POD class. Constructors and (non-virtual) methods are > > > irrelevant. > > Just a nit, but it's possible to implement polymorphism with > > no additional information in the instance itself; you could, > > for example, maintain the information is a separate > > hashtable which mapped the address to the type information. > > What isn't possible is to establish this mapping without > > executing some code. I.e. a constructor. > And how relatively (relative to the current implementation) > slow would that be is the question. I don't think anyone actually knows, since as far as I know, no one has actually implemented it this way. A virtual table look-up involves two indirections---read the vptr, then the vtbl itself; it seems pretty obvious that a hash table implementation can't come close. It might be useful, however, for instrumenting the code, in order to generate various statistics, or even doing some additional error checking on the side (although I'm not sure what). As I said above, my comment was just a nit---it's possible to implement polymorphism with no information about the type in the class object itself. Conceptually, at least; it's probably not practical. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
#19
| |||
| |||
| On Nov 6, 11:29 pm, tonytech08 <tonytec...@gmail.com> wrote: > On Nov 4, 3:06 am, James Kanze <james.ka...@gmail.com> wrote: > > On Nov 3, 11:55 pm, tonytech08 <tonytec...@gmail.com> wrote: > > > On Nov 3, 4:25 pm, James Kanze <james.ka...@gmail.com> wrote: > > > > On Nov 3, 8:44 pm, tonytech08 <tonytec...@gmail.com> wrote: > > > > > On Nov 1, 3:32 am, James Kanze <james.ka...@gmail.com> wrote: > > > > > > On Nov 1, 4:02 am, tonytech08 <tonytec...@gmail.com> wrote: > > > > > > > What I like about the C++ object model: that the data > > > > > > > portion of the class IS the object (dereferencing an > > > > > > > object gets you the data of a POD object). > > > > > > No it doesn't. > > > > > class SomePODClass > > > > > { > > > > > public: > > > > > int first_int; > > > > > int second_int; > > > > > void Func1(){} > > > > > }; > > > > > SomePODClass X; > > > > > int first_int_in_obj = *(int*)&X; // this is not pretty, but true > > > > But it's only true for POD types, > > > Well that's why I added the parenthetical part in my > > > original post: to make clear I was referring to what I > > > like about the C++ model and wish it wouldn't get > > > abberated so quickly by changing the memory representation > > > of the data portion. 'POD' was very key for my thought, > > > though could have been worded better to show that I guess. > > Well, PODs make up part of the C++ object model; one > > important aspect of it is that PODs do behave differently > > from objects which have non-trivial constructors or > > destructors. The main reasons for this are probably linked > > with C compatibility, but it was always intended in C++ that > > you could create simple structures which were no more than a > > collection of data (with or without member functions), as > > well as full OO type objects. The object model of C++ is > > designed to support both. > Thanks for reiterating my thought: C++ has more support for OO > with "full OO type objects". More support than what. C++ has support for "full OO type objects", if that's what you need. Most of my objects aren't "full OO type objects", in the sense that they don't support polymorphism. C++ supports them just as well. > > > > and only because of constraints of C compatiblity. The > > > > data portion of the class isn't the object in general. > > > I tend to think of the data portion (noun, vs. > > > behavior=verb) as "the thing" because that's what get's > > > operated on and maybe even directly manipulated. > > In C++ (and even in C, for that matter), an object has a > > type and an address; the type determines its size, and the > > set of legal operations on it. Since an object is a thing, > > in some way, I guess it is a noun, but even a POD struct has > > behavior: you can assign it, for example, or access members. > > Compared to C, C++ adds the ability for the user to define > > additional operations (member functions), and to define > > non-trivial initialization and destruction (which forces > > significant changes in the object model). Beyond that, C++ > > adds support for dynamic typing (which is what one usually > > understands with OO). > Not sure what your point is. I said that I consider the data > portion of an object, "the object". But that's simply wrong, at least in the C++ object model. An object has a type. Otherwise, it's just raw memory. That's a fundamental principle of any typed language. > I wasn't trying to be implementation literal about it. Yes, > data+behavior= class, but when the implementation starts > adding things to the data portion, that defines a different > animal than a POD class. But the implementation *always* adds things to the data portion, or controls how the data portion is interpreted. It defines a sign bit in an int, for example (but not in an unsigned int). If you want to support signed arithmetic, then you need some way of representing the sign. If you want to support polymorphism, then you need some way of representing the type. I don't see your point. (The point of POD, in the standard, is C compatibility; anything in a POD will be interpretable by a C compiler, and will be interpreted in the same way as in C++.) > > [...] > > > > It restricts the use of OO concepts to classes designed to > > > > be used with OO concepts. > > > Not really, since one can have POD classes with methods, > > > just not CERTAIN methods (you are suggesting that "classes > > > designed to be used with OO concepts" are those > > > heavyweight classes that break PODness, right?). > > No. I'm really not suggesting much of anything. However you > > define the concept of OO, the concept only applies to classes > > which were designed with it in mind. C++ doesn't force any > > particular OO model, but allows you to chose. And to have > > classes which aren't conform to this model. > "Allows you to choose"? "FORCES you to choose" between > lightweight (POD) class design with more limited OO and and > heavyweight (non-POD) class design with all OO mechanisms > allowed but at the expense of losing POD-ness. It's a > compromise. I'm not saying it's a bad compromise, but I am > wondering if so and what the alternative implementation > possibilities are. Obviously, you have to choose the appropriate semantics for the class. That's part of design, and is inevitable. So I don't see your point; C++ gives you the choice, without forcing you into any one particular model. And there aren't just two choices. > > > You seem to be saying that POD classes are not supported > > > or at least not encouraged. > > Where do I say that? POD classes are definitely supported, > > and are very useful in certain contexts. They aren't > > appropriate for what most people would understand by OO, but > > so what. Not everything has to be rigorously OO. > You seemed to imply that the "supported" ("ecouraged" would > probably be a better word to use) paradigms were: A. data > structs with non- trivial member functions and built-in > "behavior" and B. "full OO type objects". Not at all. You define what you need. From a design point of view, I find that it rarely makes sense to mix models in a single class: either all of the data will be public, or all of it will be private. But the language doesn't require it. > > > That would be a real downer if true. I'd like to see more > > > support in the langauge for POD classes. > > Such as? > What I call "initializing constructors" for one thing. > (Constructors that take arguments to initialize a POD class in > various ways). Well, if there is a non-trivial constructor, the class can't be POD, since you need to call the constructor in order to initialize it. Anything else would be a contradiction: are you saying you want to provide a constructor for a class, but that it won't be called? That doesn't make sense. > > Part of the motivation for defining POD as a special > > category is C compatibility; a POD should be usable in C. > > Beyond that, there is a wide range of things you can do. > Can't construct conveniently as you can with heavyweight class > objects. Why allowing this would break POD-ness escapes me. Because you can't have a constructor in C, basically. Because the compiler must generate code when the object is created, if there is a constructor. That is what POD-ness is all about; a POD object doesn't require any code for it to be constructed. > Perhaps it would break C-compatibility? Certainly, since you couldn't instantiate an instance of the object in C. > Maybe defining POD-ness as "C compatibility of structs" is a > hindrance, if it is defined something like that. The next version of the standard does have an additional category "layout compatible". I'm not sure what it buys us, however. > > > I don't know how much can be implemented before it becomes > > > impossible. Certainly initializing constructors can be > > > had? > > A non-trivial constructor causes changes in the way object > > lifetime is defined. So the results aren't (and can't be) a > > POD. The justification is simple: you can't define an > > object with a non-trivial constructor in C. > So it is just the backward compatibility with C that prevents > having those nifty constructors? Interface compatibility. And if you're not interfacing with C, you can have them. The object won't be a POD, but if you're not using it to interface with C, who cares? > > > Polymorphism not, but only NOT because of the way C++ > > > implements it? > > Polymorphism implies a non-trivial constructor. Regardless > > of how it is implemented, something must occur (some code > > must execute) for the raw memory to assume its type. > The more obvious issue with the polymorphism implementation is > the vptr. But I'm not too worried about not being able to > derive from POD- classes (for now anyway). But you can derive from a POD class. A pointer to a POD class just won't behave polymorphically. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
#20
| |||
| |||
| In article <e60dbedd-a21a-4542-9e56- 21b46587af5d@v16g2000prc.googlegroups.com>, james.kanze@gmail.com says... [ ... ] > I don't think anyone actually knows, since as far as I know, no > one has actually implemented it this way. A virtual table > look-up involves two indirections---read the vptr, then the vtbl > itself; it seems pretty obvious that a hash table implementation > can't come close. It might be useful, however, for > instrumenting the code, in order to generate various statistics, > or even doing some additional error checking on the side > (although I'm not sure what). > > As I said above, my comment was just a nit---it's possible to > implement polymorphism with no information about the type in the > class object itself. Conceptually, at least; it's probably not > practical. I can think of a way that might be practical. Allocate objects in pools of (say) one megabyte (of virtual address space) apiece. All objects in a given pool are of the same type. A vtable for that pool of objects is located at the beginning of the one megabyte range, so you can get from an object to its vtable by anding out the bottom 20 bits of the object's address. This could waste a little bit of address space if you had more than one megabyte of a given type of object, but _could_ also be somewhat faster than the usual current implementation -- it substitutes a CPU operation (usually quite fast) for a memory access (often a lot slower). -- Later, Jerry. The universe is a figment of its own imagination. |

