DM> A quick paraphrase of my understanding of default constructor is one
DM> that does not require any explicit arguments.
RH> Thanks. Does indeed seem the most logical thing. Book
RH> got me confused when it so explicitly declared a
RH> constructor without any arguments while simply adding
RH> an extra default argument to the other constructor made
RH> it functionally equivalent.
In this case they (could) do the same thing - but that may not always be the
case.
DM> If the book is calling this an "instance", mentally switch it to
DM> "object".
RH> Now that you mention it, it actually uses "object",
RH> don't know why I called it an instance. In fact, I'm
RH> not all to sure when and why to call anything an
RH> instance. Not having English as my native language,
You're speaking it better than some people I know whose native language is
English - I wouldn't have suspected that it wasn't yours.
RH> most of the terminology is quite literally foreign to
RH> me anyway. Now that you got me interested, under what
RH> circumstances *would* instance be proper terminology?
RH> An instance of a template?
That is one case of instance - because when you 'instantiate' (create an
instance of) a template, you are creating extra code, but not an abstract
representation of a real object.
DM> I've found that, personally, terminology has made the switch to
DM> object orientation much easier to grasp.
RH> though, building my own class hierarchies remains
RH> somewhat of a black art. Furthermore, C++ classes are
RH> rather more mature than Pascal objects were before
RH> Delphi came along, so much left to learn...
Yeah - Delphi's classes look very similar to C++'s.
RH> Yet you seem to have managed to confuse me quite nicely
RH> in your last paragraph using the *right* terminology.
RH> This object encapsulates a real object? Which object?
Your TTime objects encapsulates a real object (in this case, an abstract
object that humans believe we understand): time. "TTime now;" creates an
object "now" that encapsulates a time. What time is it? "now" can hold the
answer in a fairly understandable way, unlike a time_t which holds what
amounts to a hash of the time into something that needs to be converted into
a real time. (A TTime may also need to be converted, but that information is
all hidden from the programmer - the conversion takes place automatically.)
RH> What's a real object and why is it encapsulated? Where
RH> do abstract objects come into this? Please elaborate. :-)
Abstract objects or abstract classes? I've never heard the term 'abstract
object' before. A class is merely a description of what an object is and
what messages can be sent to it. So an abstract class is merely an abstract
description - a description of a group of objects. If you know you have a
Fruit in your hand, for instance, you can Eat() it, whether it may be an
Apple, Orange, or StrawBerry. And the Eat() of an Orange may take the rinds
off before you eat it.
RH> And still, he did. Thanks for the answer. You probably
RH> shouldn't have replied though, because now I will no
RH> doubt continue to bother you with all kinds of dumb
RH> questions. Have some "stylish" ones for you right now.
I haven't seen any dumb questions yet... and that's what this echo is for -
discussing C++.
RH> In both C and C++ main always seems to come first, with
RH> the functions it uses prototyped above it, and
RH> implemented below. Coming from Pascal, I always put
RH> main last, with everything implemented in full above
RH> it. Am I offending (m)any people?
I always put main last with everything implemented either in other modules
(where I have a header that is #include'd) or above it. I use prototypes
only in header files.
RH> I believe I remember reading, in this echo, a while
RH> back that the C++ style for functions which don't take
RH> any arguments is "empty parenthesis", as opposed to the
RH> "void" keyword? That is, which is generally preffered,
RH> int main(void) or int main()?
Both seem to be accepted, but the latter is the "normal" method for C++.
RH> If the void keyword is fine, does that also go for
RH> default constructors and destructors? Tom Swan never
RH> uses "void" in constructors and destructors, does use
RH> it in member functions, and doesn't use it for main.
It goes for everywhere. Both work, but the empty parenthesis is the "right"
way for everything in C++.
RH> I believe reading that in C++ the macro NULL and a
RH> literal zero are guaranteed the same? Is either
Yes. I find this somewhat stupid m'self, but...
RH> strongly preferred? Don't much care for NULL.
I vastly prefer NULL. When you initialize a variable, use the same type when
possible. It makes the code easier to read:
s = 0;
Is s a pointer? Is s an int? Is s a bool?
s = false;
Ah, NOW I know what it is. (NULL doesn't tell you exactly what it is, but
does give a clue that it is a pointer.)
RH> When implementing member functions inline in the class
RH> declaration, the consensus seems to be to cram it all
RH> on a single line. Is it considered bad style to spread
If it is a single return statement (perhaps returning a calculation), I'll
sometimes cram it out... otherwise never.
RH> it out some more? Ie:
RH> class TExample {
RH> private:
RH> char *s;
RH> public:
RH> TExample(void) // or TExample() ?
RH> {
RH> s = 0; // or NULL ?
RH> }
Use the one in comments for both - but, yeah, spreading it out will make it
more readable. One exception may be functions that merely redirect calls...
class foo
{
private:
/*class*/ bar* b;
public:
int baz(int i) { return b->baz(i); }
int baz(char* c) { return b->baz(c); }
int baz(float f) { return b->baz(f); }
};
Spreading this out would actually make it _less_ readable, IMO. But this is
a rare exception.
RH> I hate thinking up new names all the time. Is the
RH> following, using the this pointer for scope resolution,
RH> okay?
RH> TExample(char *s)
RH> {
RH> this->s = strdup(s);
RH> }
I guess... but why not:
class foo
{ // not that I normally do this, but private is implied at the to of a class
char* m_s;
public:
TExample(char* s)
{ m_s = strdup(s); }
};
Any time I see "m_" in front of a variable, I know I can find its definition
in the class - it is local to the class, but still global in that it can be
modified by multiple functions. Another possibility in this case is:
TExample(char* s) : s(strdup(s))
{}
But this is using the ability in C++'s constructors to use the constructors
of its member variables.
RH> The book warns against not mixing C and C++ memory
RH> allocation features, yet it keeps doing things like:
RH> ~TExample(void) // or ~TExample() ?
RH> {
RH> delete s;
RH> }
That's plain wrong. You're right on both accounts:
- if s were new'd, it would be new[]'d. Thus this should be delete[].
- s wasn't new[]'d - it should thus be free'd.
I also have a "cchar" class that handles the strdup/delete paradigm for you -
it puts an array on the heap but it looks like any other array on the stack -
you don't have to delete it. :-)
RH> Last, would you happen to know if/where one might
RH> obtain a copy of the (draft) ANSI C++ standard? I
RH> remember reading that question in here before, but I
RH> never saved an answer (if there was any).
Someone else may help you there - I just go by what my compiler allows me to
do ... if it doesn't allow it (yet), there's no point in doing it even if the
standard allows it. :-)
RH> Hope I didn't ask too many questions at once. Please be
RH> aware that if you do reply I will very likely have some
RH> more lined up for you by that time... :-)
And I probably won't be the only one answering... good luck!
---
---------------
* Origin: Tanktalus' Tower BBS (1:250/102)
|