drdobbs C++ Made Easier: The Rule of Three
An Example and a Misconception
NOTE:
1、原文给出的这个例子是非常具有代表性的。
这个例子,导致错误是double free,它的implicit defined copy constructor是shallow copy的
#include<iostream>
// This class contains a subtle error
class IntVec
{
public:
IntVec(int n) :
data(new int[n])
{
}
~IntVec()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
delete[] data;
}
int& operator[](int n)
{
return data[n];
}
const int& operator[](int n) const
{
return data[n];
}
private:
int *data;
};
int main()
{
IntVec x(100);
IntVec y = x; // Trouble!
return 0;
}
// g++ test.cpp -pedantic -Wall -Wextra
Fixing Our Class
Non-copyable
#include<iostream>
// This class contains a subtle error
class IntVec
{
public:
IntVec(int n) :
data(new int[n])
{
}
~IntVec()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
delete[] data;
}
int& operator[](int n)
{
return data[n];
}
const int& operator[](int n) const
{
return data[n];
}
private:
int *data;
// these two member functions added
IntVec(const IntVec&);
IntVec& operator=(const IntVec&);
};
int main()
{
IntVec x(100);
IntVec y = x; // Trouble! compile error
return 0;
}
// g++ test.cpp -pedantic -Wall -Wextra
Rule of three
#include<iostream>
// This class corrects the error by
// defining copying and assignment
class IntVec
{
public:
IntVec(int n) :
data(new int[n]), size(n)
{
}
~IntVec()
{
delete[] data;
}
;
int& operator[](int n)
{
return data[n];
}
const int& operator[](int n) const
{
return data[n];
}
IntVec(const IntVec &v) :
data(new int[v.size]), size(v.size)
{
std::copy(data, data + size, v.data);
}
IntVec&
operator=(const IntVec &v)
{
int *newdata = new int[v.size];
std::copy(v.data, v.data + v.size, newdata);
delete[] data;
data = newdata;
size = v.size;
return *this;
}
private:
int *data;
int size;
};
int main()
{
IntVec x(100);
IntVec y = x; // Trouble!
return 0;
}
// g++ test.cpp -pedantic -Wall -Wextra