2012-01-07 5 views
2

у меня есть отношения композиции между класса А и В,конструктор копирования и состав

class A 
{ 
    A(); //default constructor //EDIT 
    A(const A &mA); // copy constructor //EDIT 
    virtual ~A(); 
}; 


class B 
{ 
B(A *pA); //constructor 
B(const B &mB) //copy constructor 
virtual ~B(); //EDIT: destructor to eliminate mA and to build the composition 
A* mA; 
}; 

Могу ли я написать конструктор копирования таким образом:

B(const B &mB, A *pA) 

мне нужно идти в ногу состав также между скопированными объектами. Неправильно? Существует ли лучшее решение? Спасибо

EDIT: Я постараюсь объяснить мне лучше. Я хочу копию объекта mB и объекта mA. Но если в конструкторе копирования у меня был написан mA = mB.mA, я бы скопировал адрес в исходный объект mA. Поэтому я думаю, что мне нужна глубокая копия, а не ласточка. Моя путаница возникает из-за того, что теперь, из основного, сначала копирую объект mA, а затем копирую mB. Делая это, я думаю, что нужно назначить скопированный объект м с внешней функцией, как

foo(A *pA) 

В противном случае я мог бы решить эту проблему, если бы я мог делать глубокую копию тВ. Это называется глубокой копией?

P.S. A и B - абстрактные классы

+6

Вы можете написать эту функцию, но это не конструктор копирования. –

+0

@BenjaminLindley: Вероятно, это должен быть ответ ... –

+1

@OliCharlesworth: У меня нет лучшего решения (потому что я не совсем уверен, что он пытается решить), и я думаю, что это мясо вопроса так или иначе. –

ответ

6

№ По определению конструктор копирования не может иметь подпись, подобную той, которую вы описали. Вот несколько действительных сигнатур для конструкторов копирования:

B(const B &); 
B(B &); // Thanks Oli! 

Зачем оно вам нужно? Вы можете получить доступ к элементу мА внутри конструктора копии, делая что-то вроде этого (я мог бы сделать некоторые синтаксические ошибки):

B::B(const B & original) 
{ 
    mA = original.mA; 
} 
+2

Чтобы быть педантичным, существует несколько других допустимых сигнатур для конструктора копирования (например, 'B (B &)'). –

+0

это способ сделать это! – davogotland

+4

Это не определение конструктора копии, поэтому «По определению» неточно. Например. 'B (const B & mB, A * pA = 0)' будет конструктором копирования. –

0

Вы можете быть overthinking это. Конструктор копирования просто должен инициализировать все члены с соответствующими значениями исходного объекта, например. как так:

B(B const & rhs) : mA(rhs.mA) { } 

Это просто тривиальная копия, хотя, так что если нет ничего другого ему, то вы бы лучше не писать конструктор копирования на всех.

С другой стороны, если вы хотите глубокой копии, это может быть что-то вроде этого:

B(B const & rhs) : mA(::new A(rhs.mA)) { } 

Однако детали, которые зависят от реальной политики собственности класса B в отношении указатель mA. В зависимости от этих деталей не забудьте написать соответствующий деструктор, если это необходимо.

Вы также должны написать оператор присваивания соответствия вашего конструктора копии делает что-то нетривиальное, например:

B & operator=(B const & rhs) 
{ 
    if (this != &rhs) 
    { 
     A * tmp = ::new A(*rhs.mA); // need try/catch in general! 
     ::delete mA; // OK, no exception occurred if we got here 
     mA = tmp; 
    } 
    return *this; 
} 
+0

А, да! Хорошая точка зрения! Ясно, что я думал о операторе присваивания. (Хотя 'B b (b)', вероятно, будет компилироваться ...) –

+0

@OliCharlesworth: Я объявлю «B b (b);« как «UB из-за PEBKC» и не беспокоюсь. –

+0

@OliCharlesworth: Я также добавил ass.operator для удовольствия. Это еще больше доказательство самоопределения, которое строго необходимо :-) –

Смежные вопросы