Re: The C++ Object Model: Good? Bad? Ugly?
On Nov 7, 4:40 am, James Kanze <james.ka...@gmail.com> wrote:
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.
More support for OO with "heavyweight" classes than for POD classes.
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.
I think I may be OK without polymorphism in "lightweight" classes, but
overloaded constructors sure would be nice. And conversion operators.
Can a POD class derive from a pure abstract base class? That would be
nice also if not.
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,
No it's not. It's just an abstract way of looking at it. It's hardly a
stretch either, since the C++ object model or at least most
implementations use that as the foundation upon which to implement
polymorphism: tacking a vptr onto "the thing part" (noun) of "the
object".
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 could easily go further and say something like "the memory in which
the data portion of an object, is the object". While that may bother
purists, it is a valid abstract way of thinking about it.
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++.)
Well maybe I'm breaking new ground then in suggesting that there
should be a duality in the definition of what a class object is. There
are "heavyweight" classes and "lightweight" ones. I use C++ with that
paradigm today, but it could be more effective if there was more
support for "object-ness" with "lightweight" classes. The limitation
appears to be backward compatibity with C. If so, maybe there should
be structs, lightweight classes, heavyweight classes.
Of course I can only ruminate about such things being implemented in C+
+ in the future. I am beginning to investigate either preprocessing
"my language" to C++ or full new language implementation (though the
latter seems only doable if I could hack an existing C++
implementation and supplant it with an improved object model).
[...]
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.
The change occurs when you do something to a POD ("lightweight") class
that turns the data portion of the class into something else than just
a data struct, as when a vptr is added. Hence then, you have 2
distinct types of class objects that are dictated by the
implementation of the C++ object 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.
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.
There are the limitations though: you can't have overloaded
constructors, for example, without losing POD-ness. Or conversion
operators (?). Or derivation from "interfaces" (?).
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.
Well maybe then "POD" is the hangup and I should have used
"lightweight" from the beginning. I just want the data portion to
remain intact while having the constructor overloads and such.
Polymorphism I can probably do without, but deriving from interfaces
would be nice if possible.
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?
Of course I want it to be called. By "POD-ness" I just meant I want a
struct-like consistency of the object data (with no addition such as a
vptr, for example).
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.
Then apparently I was using "POD" inappropriately. My concern is the
in-memory representation of the object data.
Perhaps it would break C-compatibility?
Certainly, since you couldn't instantiate an instance of the
object in C.
That pesky C-compatibility constraint! A good reason for investigation
of "a better C++" (as of course I am pondering already).
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.
Where can I read up on 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?
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?
I don't. I didn't know that that is all I would be "breaking". I was
worried that putting overloaded constructors into "lightweight"
classes may either now or in the future aberrate my "data objects" in
some way. As long as the data portion of the object looks like a
struct of just the data in memory, I'm a happy camper.
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.
Of course not, because you can't define a virtual function and still
have a POD class. The thing you end up with is a non-POD though
because PODs can't have base classes. Whether I can derive from a POD
and still have one of my "lightweight" classes is a question (?).