Чтобы прокомментировать сказанное @ [don.neufeld.myopenid.com], это не только мелкая копия, но или утечка памяти или свисающий указатель.
// memory leak (note that the pointer is never deleted)
class A
{
B *_b;
public:
A()
: _b(new B)
{
}
};
// dangling ptr (who deletes the instance?)
class A
{
B *_b;
public:
A()
... (same as above)
~A()
{
delete _b;
}
};
Чтобы решить эту проблему, есть несколько методов.
Всегда реализуйте конструктор копирования и оператор = в классах, которые используют необработанные указатели памяти.
class A
{
B *_b;
public:
A()
... (same as above)
~A()
...
A(const A &rhs)
: _b(new B(rhs._b))
{
}
A &operator=(const A &rhs)
{
B *b=new B(rhs._b);
delete _b;
_b=b;
return *this;
};
Само собой разумеется, это большая боль, и есть много тонкостей, чтобы понять правильно. Я даже не совсем уверен, что сделал это прямо здесь, и я делал это несколько раз. Не забывайте, что вам нужно скопировать всех участников - если вы добавите новые позже, не забудьте добавить их тоже!
Сделайте конструктор копирования и оператор = private в вашем классе. Это решение «запереть дверь». Это просто и эффективно, но иногда чрезмерно защищает.
class A : public boost::noncopyable
{
...
};
Никогда не используйте сырые указатели. Это просто и эффективно. Здесь есть много вариантов:
- Использовать строковые классы вместо необработанных указателей на символы
- Используйте std :: auto_ptr, boost :: shared_ptr, boost :: scoped_ptr и т. Д.
Пример: * * тысяча двадцать-восемь
// uses shared_ptr - note that you don't need a copy constructor or op= -
// shared_ptr uses reference counting so the _b instance is shared and only
// deleted when the last reference is gone - admire the simplicity!
// it is almost exactly the same as the "memory leak" version, but there is no leak
class A
{
boost::shared_ptr<B> _b;
public:
A()
: _b(new B)
{
}
};