В родительской таблице попробуйте установку
border-collapse:separate;
border-spacing:5em;
Плюс объявление границы и посмотрите, достигает ли это Вашего желаемого эффекта. Остерегайтесь, тем не менее, что IE не поддерживает "разделенные границы" модель.
Вы можете попробовать следующий код:
foo(const foo& rhs)
: _a(rhs._a)
, _b(rhs._b)
, _c(_rhs._c.get() ? new bar(*_rhs._c.get()) : 0)
{
}
(Оператор присваивания аналогичен.)
Однако это будет работать, только если bar
будет CopyConstructible и если это действительно делает что хотите. Дело в том, что оба объекта foo
( _rhs
и сконструированный) будут иметь разные указатели в _c
.
Если вы хотите, чтобы они разделяли указатель, тогда вы не должны использовать auto_ptr
, поскольку он не поддерживает совместное владение. Рассмотрим в таком случае использование shared_ptr
из Boost.SmartPtr , например (который будет включен в новый стандарт C ++). Или любая другая реализация общего указателя, поскольку это настолько распространенная концепция, что доступно множество реализаций.
Как вы обнаружили, вы не можете скопировать std :: auto_ptr
таким образом. Кто владеет указанным объектом после копии? Вместо этого вы должны использовать умный указатель с подсчетом ссылок. В библиотеке Boost есть shared_ptr , который вы можете использовать.
Во-первых, я бы избегал auto_ptr
Передача права собственности хороша в некоторых сценариях, но я считаю, что они редки, и теперь легко доступны «полноценные» библиотеки интеллектуальных указателей. (IIRC auto_ptr был компромиссом для включения хотя бы одного примера в стандартную библиотеку без задержек, которые потребовались бы для хорошей реализации.)
См., Например, здесь
или здесь
Определите семантику
] Должна ли копия foo содержать ссылку на тот же экземпляр bar? В этом случае используйте boost :: shared_ptr
или ( boost :: intrusive_ptr
) или аналогичную библиотеку.
Или нужно создать глубокую копию? (Иногда это может потребоваться, например, при наличии состояния с задержкой). Я не знаю какой-либо стандартной реализации этой концепции, но создать ее аналогично существующим интеллектуальным указателям несложно.
// roughly, incomplete, probably broken:
template <typename T>
class deep_copy_ptr
{
T * p;
public:
deep_copy_ptr() : p(0) {}
deep_copy_ptr(T * p_) : p(p_) {}
deep_copy_ptr(deep_copy_ptr<T> const & rhs)
{
p = rhs.p ? new T(*rhs.p) : 0;
}
deep_copy_ptr<T> & operator=(deep_copy_ptr<T> const & rhs)
{
if (p != rhs.p)
{
deep_copy_ptr<T> copy(rhs);
swap(copy);
}
}
// ...
}
std :: auto_ptr
- хороший инструмент для управления динамическими объектами в C ++, но для того, чтобы использовать его эффективно, важно понимать, как работает auto_ptr. В этой статье объясняется, почему, когда и где следует использовать этот интеллектуальный указатель.
В вашем случае, прежде всего вы должны решить, что вы хотите делать с объектом внутри вашего auto_ptr. Клонировать или делиться?
Если его нужно клонировать, убедитесь, что у него есть конструктор копирования, а затем создайте новый auto_ptr, который содержит копию вашего объекта, см. Ответ Адама Бадура .
Если нужно shared, вы должны использовать boost :: shared_ptr , как предложил Martin Liversage .
Мой первый выбор - вообще избегать auto_ptr в этой ситуации. Но если бы я был прижат к стене, я мог бы попытаться использовать ключевое слово mutable
в объявлении _c - это позволит изменить его даже из константной ссылки.
После редактирования, похоже, вы хотите передать семантику владения.
В этом случае, тогда вы ' Я захочу, чтобы ваш конструктор копирования и оператор присваивания принимали неконстантные ссылки на свои аргументы и выполняли там инициализацию / присвоение.
Вся идея auto_ptr
состоит в том, что есть только один владелец упомянутого объекта. Это означает, что вы не можете скопировать указатель, не удалив первоначального владельца.
Поскольку вы не можете скопировать его, вы также не можете скопировать объект , содержащий и auto_ptr
.
Вы можете попробовать использовать семантику перемещения, например, используя std :: swap
вместо copy.
Если у меня есть класс, содержащий auto_ptr, и мне нужна семантика глубокой копии, я обычно использую только это для классов, у которых есть виртуальный оператор копирования, например clone ().
Затем в конструкторе копирования я инициализирую auto_ptr как clone () другого; например,
class Foo
{
public:
Foo(const Foo& rhs) : m_ptr(rhs.m_ptr->clone());
private:
std::auto_ptr<T> m_ptr;
};
clone () обычно реализуется следующим образом:
class T
{
std::auto_ptr<T> clone() const
{
return std::auto_ptr<T>(new T(*this));
}
};
Мы налагаем условие, что T является клонируемым, но это условие, по существу, налагается наличием копируемого класса с членом auto_ptr.
Вы не можете использовать константные ссылки в конструкторе копирования или операторе присваивания, который включает auto_ptr <>
. Удалите константу. Другими словами, используйте объявления типа
foo(foo & rhs);
foo & operator=(foo & rhs);
. Эти формы явно упоминаются в Стандарте, в первую очередь в разделе 12.8. Их следует использовать в любой соответствующей стандарту реализации. Фактически, параграфы 5 и 10 из 12.8 говорят, что неявно определенный конструктор копирования и оператор присваивания (соответственно) будет принимать неконстантную ссылку, если это требуется любому из членов.