Subject: Re: commit: UT_String (longish)
From: Dom Lachowicz (dominicl@seas.upenn.edu)
Date: Sun Jun 03 2001 - 00:27:10 CDT
> I hope I'm not (too) rude in this comment, it's not my intention.
Rude - yes. Too rude - no. I hope that my email doesn't come off as too rude
either - it's not my intention either.
> > Just because a class was originally designed to fit well into
> > one situation does not mean that it cannot be adapted to better fit
> > into another framework.
>
> True, but I fail to see how adding a vftable to it is adapting it to
> better
> fit into AbiWord.
I still fail to see why adding a vftable is bad. I doubt that you'll ever
convince me of this.
> > I'm sorry if C++ doesn't give you virtual functions
> > for free (or by default) like Java does.
>
> You're sorry "if"? Shouldn't that have been your sorry "that"? Btw, I'd
> _really_ like to see you trying to explain that "every function is
> virtual"
> in Java comes "for free". ;->
They actually do come for free, but here I meant it more as "you don't need an
explicit keyword to declare a function as virtual, they just are."
> > They don't add all that much bloat either, though.
>
> So a little bloat is OK? I'm sorry, but I think _that's_ flawed
> thinking.
No it's not. Adding a very small vftable lookup is *trivial* if it helps you
better achieve the said goal that you're striving for.
> > However, overloaded freestanding functions are a major flaw in C++,
> and
> > desperately show the problems that arise by not having some common
> > anscestor class and reek of C++'s C-based heritage.
>
> Perhaps you should try that argument in e.g. comp.lang.std.c++. Expect
> to be
> educated. :-)
Doubtful. For starters, everyone in comp.lang.java would tend to disagree, my
friend, and that'd be quite an education too :-) I don't want to get into
another language flamewar like that whole Lisp scenario. We are using C++. C++
is a big language with many accepted ways of approaching a problem. I'm using a
java-ish approach here, which (to the best of my knowledge) isn't frowned upon.
Getting a cleaner and more flexible and maintainable design for a *minute*
overhead is totally acceptable, IMHO.
[snip]
> No no no no no no no! Absolutely NOT!
>
> UT_HashableString
> {
> public:
> UT_HashableString(const UT_String s /* value semantics */);
> UT_uint32 hashcode() const;
> ...
> private:
> UT_String m_str;
> };
>
> UT_Map::add(UT_HashableString key, Object o)
> {
> UT_uint32 k = key.hashcode();
> m_pimpl->add (o, k);
> }
>
> or
>
> UT_uint32 hashcode(const UT_String& s);
>
> UT_Map::add(const UT_String& key, Object o)
> {
> UT_uint32 k = hashcode(key);
> m_pimpl->add (o, k);
> }
You still haven't addressed my problems, or perhaps you still don't see them:
1) Only pre-known types can be keys in the HashMap (or else you need a good bit
of trickery to get around this)
2) You still have my scenario where you want things other than strings to be
keys....
3) Keeping proper track of memory management/pointers
> I sure hope you're not planning on allowing windows, views and documents
> (all planned to be inherited from the XAP_AbiObject?) to be keys into
> the
> same map, are you?!
>
> Not. To put icing on the cake it's not (type-) safe either.
Wow.. take away templates and the whole world goes amuck? rtti is great if we
ever need to use it. Considering we're not using type-safe values either, I
fail to see your point. We still have problems with storing and retrieving key
values. Then if we want keys under the current UT_Map, would you suggest this
for storing the key?
union keyval {
UT_String m_str;
const void * m_void;
...
};
> First let me explain that these are two separate issues. You're trying
> to
> cram two unrelated behaviors into one class. That is a design error.
This isn't necessarily the case, unless you're frowning on the whole concept of
multiple inheritance too (in the C++ or Java-interface POV). Here I probably am
doing something wrong and it is probably a design error. In general, it need
not be. There's a *very* important distinction between the two.
> 2. The way it's designed it makes it impossible to reference cons
> objects.
> Perhaps ref(), unref() and sink() should be const, and m_refs should be
> mutable?
>
> 3. The experimental memory management only contains "delete" for objects
> partially constructed (when exception is thrown). Perhaps the normal
> "delete" also should be added. What about the array versions, are they
> going
> to go through the system memory management?
>
> 4. It contains the Java construction "equals". Silly, and dangerous,
> since
> in C++ we have a global operator==() for any types which does
> comparison.
> Since this (virtual) compare function returns equality of pointers, no
> subclass can change that behaviour without violating the LSP (Barbara
> Liskov - "Liskov Substitution Principle"). It also allows comparison of
> any
> types inherited from it, e.g. a string and a document. Not only silly,
> but
> completely wierd and useless. If it is to only let objects compare for
> "value" equality (not pointer equality) it should be a pure
> virtual. To at least try to mimic C++ it should also be named "equal"
> without the "s".
>
> 5. It contains no copy constructor, making it completely useless unless
> we
> add a clone() member function. Note that such a clone() function can't
> use
> a covariant return type since (bloody) M$ can't get their act together
> (this
> is proven). How can you ref-count anything unless you can make copies of
> it???
#1 && 2 - The class was not finished and this is exactly the type of feedback I
was looking for.
#3 - this is exactly why they aren't turned on. i hate that C++ lets you do
your own memory management, and i was hoping that you (seemingly the only c++
"guru" in the house) would help me finish things up
#4 - what i was aiming for is perhaps the following Java-ish example:
bool String.equals (Object o) {
if (! (o instanceof String) )
return false;
else if (strcmp (this.buf, ((String)o).buf) == 0)
return true;
return false;
}
IIRC, In Java, Object.equals() returns "pointer" equality if the method isn't
overridden. This is what I hoped to get here.
#5 - The argument about the copy constructor/clone is well taken. However, it's
important to note you don't need to make copies of an object to ref-count it,
though your argument holds for Objects created on the stack instead of the
heap. I'm not a big fan of creating Objects on the stack, though...
> Perhaps the following links can provide some interesting reading also?
>
> http://www.gotw.ca/gotw/043.htm
> http://www.gotw.ca/gotw/044.htm
> http://www.gotw.ca/gotw/045.htm
I'll read up after I get some sleep.
Take care,
Dom
This archive was generated by hypermail 2b25 : Sun Jun 03 2001 - 00:27:33 CDT