Douglas Gregor wrote:
On Wednesday 12 December 2001 03:49 am, you wrote:
I think it is possible to be more specific about the kind (can't use the word class here) of class I intend to represent by volatile. It contains only values by member, and pointers to memory which it has allocated on construction or in an explicit "init (or open, or allocate)" type of call, which are explicitly freed in its destructor, or in an explicit "destroy (or close, or free)" type of call. It has only the default copy operator.
There's a big difference between these two: if they allocate in the constructor and deallocate in the destructor, but don't copy the resources then there is a serious design flaw here. The fix is not to change std::vector, but to either: 1) Make the copy constructor/copy assignment operator do the right thing 2) Make the class explicitly noncopyable (pass pointers around instead) 3) Make the class a lightweight "handle" (basically a boost::shared_ptr) to the actual resources allocated.
All cases allow some form of usage in std::vector; 1 & 3 allow direct usage, whereas 2 requires that the object be explicitly allocated. All cases also avoid the ability to shoot oneself in the foot, and don't require changes to std::vector.
A struct with no member functions, which contains pointers to allocated memory, and for which there exist helper functions to allocate and delete the memory associated with the pointers, fits this description, and is exactly what is found in a lot C style programming.
... and there is no reason why such a class would not be safely CopyConstructable. Something like this is already usable in std::vector, you just have to deal with allocation/deallocation on your own.
I think that being able to use STL in a shop full of C style programs and programmers is a good thing.
Perhaps.
It lowers the threshold for entry into the STL and C++ style of programming.
I disagree with this completely. If a programmer new to C++ has to deal with objects whose destructors should not be called, they _will_ be confused. One of the basic tenets of C++ is that destructors will be called on all deallocated objects.
Vector resizing is not impossible for such a structure. How to: Default copy is made (exactly copy of values and pointers) and no destructor is called afterwards.
That's what I meant when I said "destructor should not be called after copy operation".
Again, one has to essentially subvert the C++ type system to make this possible, and break with C++ traditions. A class type that requires this behavior can't be passed as an argument to a function, or can't be returned (unless the return-value optimization is supported: do you really want your object's behavior to differ depending on a legal optimization?)
Does SGI or Boost have a trait assigned for all predefined types?
boost::is_fundamental<T>::value
I'd be happy to see this type of object go gently into that good night. I'm a big fan of the "a type must be either CopyConstructable or Noncopyable." If my name was Scott Meyers, I'd put that in a book :)
I think that is the correct conclusion ... given infinte dealines and a universal desire to adopt STL programming in a single gulp. Only if we live in a less than ideal world is there any reason to do otherwise.
It's not really an STL issue, however. If we're going from C, which has no notion of construction or destruction, to C++, which has both construction and automatic destruction, we need to watch out for "half-breeds." The kinds of types we were talking about earlier, where the constructor allocates, destructor deallocates, but the copy constructor doesn't copy fall into this category. They aren't C structures, because they have constructors; however, they aren't safe C++ classes, because they can easily be used in ways that will break.
Wouldn't it take longer for programmers not familiar with C++ semantics to figure out why they can't now pass these structures as arguments that it would just to fix the structures themselves? One quick fix: make all of the raw pointers into boost::shared_ptrs. Then the default copy constructor/copy assignment operator will handle reference-counting automatically.
Using boost::shared_ptrs is a very good idea. It relieves the need for any modification, which in some cases is more work than not using std::vector, but some other mechanism instead. Thanks for your very useful advice and comments. Hicks
Doug
Doug
Info: http://www.boost.org Wiki: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl Unsubscribe: mailto:boost-users-unsubscribe@yahoogroups.com
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
[Non-text portions of this message have been removed]