Exercising in copy constructors and assignment operators I've just created an implementation of array to train myself in copy constructors, assignment operators, and exception safety.  Please look at this code and tell me what is wrong here.

class DumbArray {
public:
  DumbArray(size_t sz)
    : _size(sz), _buf(new int[_size])
  {
    memset(_buf, 0, _size * sizeof(int));
  }


  DumbArray(const DumbArray&amp; arr)
    : DumbArray(arr._size)
  {
    int* newMem = new int[arr._size];

    if(newMem) {
      std::copy(arr._buf, arr._buf + arr._size, newMem);
      delete [] _buf;
      _buf = newMem;
      _size = arr._size;
    }
  }


  DumbArray(DumbArray&amp;&amp; arr) {
    swap(arr);
  }


  DumbArray(std::initializer_list&lt;int&gt; ilist) 
    : DumbArray(ilist.size())
  {
    std::copy(ilist.begin(), ilist.end(), _buf);
  }


  DumbArray&amp; operator=(const DumbArray&amp; arr) {
    if(this != &amp;arr) {
      DumbArray tmp(arr);
      swap(tmp);
    }

    return *this;
  }


  DumbArray&amp; operator=(DumbArray&amp;&amp; arr) {
    swap(arr);
    return *this;
  }


  ~DumbArray() {
    // _size = 0;   // should this be done? object is being destroyed anyway, yup?
    delete [] _buf;
  }


  void swap(DumbArray&amp; arr) {
    std::swap(_buf, arr._buf);
    std::swap(_size, arr._size);
  }


  int&amp; operator[](int idx) {
    if(idx &lt; 0 || idx &gt;= _size) {
      throw std::out_of_range("Incorrect index");
    }

    return _buf[idx];
  }


  size_t size() const {
    return _size;
  }


private:
  size_t _size;
  int* _buf;
};
This is reasonably clean and reasonably complete code but I see some things that might improve your code.

Consider making this a template

There is no reason that this data structure should be limited to just storing int values.  Consider reworking it as a templated class to make it more general and to get additional practice.

Implement member functions non-inline

All of those inline functions can increase the size of your code.  If you declare them first and then have out-of-line implementations(at least for the non-trivial functions), it has advantages, especially if you decide to make this a templated class.

Consider making the destructor virtual

By having a concrete destructor rather than a virtual one, you are effectively prohibiting derived classes.  If that's not your intent, making your destructor virtual will make it possible to derive classes from this one.

List the required #include files

By my reckoning, this code requires the following to work:

#include &lt;cstring&gt;
#include &lt;initializer_list&gt;
#include &lt;iterator&gt;
#include &lt;stdexcept&gt;


These are therefore an essential part of the class interface.

Reconsider the use of size_t

Although it's used often in the C standard library, you don't really need it here, and requiring a C-flavored include file doesn't help much in keeping the interface small.  You could use unsigned instead and reduce the number of required include files.

Avoid comparing signed to unsigned

In your operator[], idx is declared as int but _size is size_t so the range check at the top of the function compares signed and unsigned numbers without a cast. Since negative numbers are already eliminated by the first clause, so you could use either a C-style cast (gasp!) or a reinterpret_cast on idx in the second clause. 

Add a default constructor

Because DumbArray has no default constructor (one with no arguments), code like this:

std::vector&lt;DumbArray&gt; dv(10);  // make ten arrays


cannot compile or run.  You could either add a default value for your existing constructor or create a new default constructor.

Consider using std::fill_n instead of memset

Instead of using the old-school 

memset(_buf, 0, _size * sizeof(int));


you might consider instead using fill_n:    

std::fill_n(_buf, _size, 0);


since you're already using the similar std::copy in one of the constructors.

Add a const version of operator[]

As it is currently written, there's no way to index into a const DumbArray.  Adding const to operator[] will fix that problem but make sure it returns a copy of an int rather than a reference to one.