FAQ 25.05 Should a template use memcpy() to copy objects of its template argument?

FAQ 25.05 Should a template use memcpy() to copy objects of its template argument?

No.

An object should be bitwise copied only when it is known that the class of the object will forever be amenable to bitwise copy. But the class of a template argument can't be known. Here is an example.

 #include <cstring> #include <new> using namespace std; template<class T> class Array { public:   Array(unsigned len=10);   Array(const Array<T>& a);                 // copy constructor   Array<T>& operator= (const Array<T>& a);  // assignment  ~Array() throw();   unsigned len() const throw();   const T& operator[] (unsigned i) const throw();   T&       operator[] (unsigned i)       throw(); protected:   unsigned  len_;   T*        arr_; }; template<class T> inline Array<T>::Array(unsigned len) : len_(len), arr_(new T[len]) { } template<class T> inline Array<T>::~Array() throw() { delete[] arr_;  } template<class T> inline unsigned Array<T>::len() const throw() { return len_; } template<class T> inline const T& Array<T>::operator[] (unsigned i) const throw() { return arr_[i]; } template<class T> inline T& Array<T>::operator[] (unsigned i) throw() { return arr_[i]; } template<class T> Array<T>::Array(const Array<T>& a) : len_(a.len_) , arr_(new T[a.len_]) {   #if 1     for (unsigned i = 0; i < len_; ++i)              <-- 1       arr_[i] = a.arr_[i];   #else     memcpy(arr_, a.arr_, len_*sizeof(T));            <-- 2   #endif } template<class T> Array<T>& Array<T>::operator= (const Array<T>& a) {   if (len_ != a.len_) {                              <-- 3     T* arr2 = new T[a.len_];     delete[] arr_;     arr_ = arr2;     len_ = a.len_;   }   #if 1     // GOOD FORM: lets the T objects copy themselves     for (unsigned i = 0; i < len_; ++i)              <-- 4       arr_[i] = a.arr_[i];   #else     // BAD FORM: manipulates the bits of the T objects     memcpy(arr_, a.arr_, len_*sizeof(T));            <-- 5   #endif   return *this; } 

(1) Good: The T objects copythemselves

(2) Bad: Manipulates the T objects

(3) Makes self-assignment harmless (see FAQ 24.03)

(4) Good: The T objects copy themselves

(5) Bad: Manipulates the T objects

If a template uses memcpy() to copy some T objects, the template must have a big, fat, juicy comment warning potential users that a class with nontrivial copy semantics might destroy the world. For example, if memcpy() were used in the example class template, and if someone created an Array<string>, it is likely that the memcpy() would create dangling references and/or wild pointers, and they would probably crash the application (see FAQ 32.01).

Finally, notice that the member functions that create T objects (that is, the constructors and the assignment operator) do not have exception specifications (see FAQ 9.04). This is because the T object's constructor may throw arbitrary exceptions, and any restrictions placed on these template member functions would be wrong for some particular type T.



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net