void f(const MouseEvent&);(...)FrameWindow w(hinst);w.onClick().add(f);vector<object> v;v.push_back(w);
such an approach does not try to elide pointers from everything and everywhere, but it allows you to do simple things simply and without having to think a lot about them.
What you called "bad design" might just too easily happen to a user of a GUI library who thinks of notifying child windows of important changes by adding those of them who care to and are able to receive such notifications to a list seperate from the main list of child windows.
So either there''s a predefined list class that implicitly doesn''t prolong lifetime of referenced objects, or the programmer has to set up the necessary mechanics himself or to think about removing children from any existing notification lists manually when they are removed during runtime.
Only for the more common case that child windows reference a parent for notification does it make no difference whether the reference is weak. And this only applies for java-like garbage collection, either.
In the case of reference counted pointers, this case is even more dangerous because it implies a circular reference. So how could this problem be solved with reasonable effort unless there are mechanics in place that encourage the use of weak smart pointers by offering a predefined collection class for this purpose with a simple interface, providing add(), remove() and notify() to notify all available elements, no-throw guaranteed?
Users else tend to simply use lists of smart pointers for the purpose, if only because these pretend to be "smart". This is exactly why I don''t really like them as part of a library''s interface. To the unexperienced programmer, they says: "Here, I''m giving you access to a pointer, but don''t be afraid, it''s SMART and will take care of itself." No, it won''t. No, it isn''t. And it should be used with exactly the same care as any pointer type.
Java-Reference-Type like behaviour and predefined collection classes that really "reference" their content in the original sense, without secretly owning and keeping it alive, make it possible to program certain, widely used things like windows and events by just "telling the computer what to do", without really having to think about the inner mechanics.
Java does not reach this noble goal. C++ can, if the library''s author is willing to, because of the possible direct access to the exact semantics. Java seems to do everything by itself, though it cannot. In C++, we have the rare opportunity to create a library with the exact semantics that we want. By enabling the user of our library to work completely without pointers, as long as it regards our library''s interfac, we bring objects back to what they originally were: data types. Just like the ints.
I think this is really one of the things the java developers had in mind when they proposed to make everything a little bit simpler. They went and sacrificed a lot of control over semantics on the shrine of simplification.
The polymorphic Bridge Pattern is the exact opposite approach: The chance for complete control over semantics is taken to reach maximal simplicity for the user, who wants a window variable to represent a window, not a pointer representing a data structure representing a system resource that provides access to a "window".
C++ is good because we are able to realize all kinds of data structures and semantics, not because it would force us to take complete control over everything, whatever we might be doing.
And C++ is good because it allows a combination of Java''s ease of programming, a lot of more possible safety and DETERMINISTIC FINALIZATION.
C++ is good, I like it.
shadi