Я пытаюсь написать два класса и B
, где B
содержит экземпляр класса A
. На практике A
содержит некоторые большие данные. В этом игрушечном примере, давайте предположим, что они являются следующие:C++ инициализация объекта, который содержит другую проблему проектирования объекта
class A{
public:
int a;
A(){}
A(const A& ac){
cout <<"copy constructor for A" << endl;
a = ac.a;
}
virtual ~A(){}
A& operator=(const A& that){
cout <<"operator = for A" << endl;
a = that.a;
return *this;
}
};
class B{
private:
A ba;
public:
B(){ a = A(); }
B(A& a){
cout << "Using default constructor" << endl;
ba = a;
}
B(const B& copy){
cout<<"copy"<< endl; ba = copy.ba;
}
B& operator=(const B& that){
cout<<"invoking operator = "<< k<< endl;
ba = that.ba;
return *this;
}
virtual ~B(){}
A& getA(){ return ba; }
void printAadrr(){
cout << &ba <<" "<< ba.a<< endl;
}
};
Проблема в том, что при инициализации B
с помощью B::B(A& a)
, аргумент копируется в экземпляр ba
в B
. Это может быть неэффективно, если a
велико.
я подумал о другом подходе, где вместо
class B{
private:
A ba;
....
я мог бы сделать
class B{
private:
A* ba;
public:
B(){
ba = new A(); //but we have to free memory in destructor if we call default constructor
}
B(A& a){
cout << "Using default constructor" << endl;
ba = &a;
}
Но этот дизайн выбор имеет свой собственный вопрос, где, если я делаю B
конструктором по умолчанию, мне нужно освободить память, выделенная для ba
позже в деструкторе.
Есть удобный способ передать «ссылку» объекта A
(создано за пределами B
) в B
в конструкторе, если мы используем B::B(A& a)
и создать пустой, по умолчанию объект A
если мы будем использовать B :: B ()? Я пробовал
B::B(A& a){
&ba = &a;
}
но он дает ошибку «lvalue должен быть слева от задания».
Любые советы приветствуются. Извините за слишком длинный пост.
C++ 11 предоставляет ссылки на _rvalue_ вместе с 'std :: move', чтобы ваши намерения были четкими. Это полезно, если вы хотите _transfer_ 'A' в' B'. В противном случае вы можете хранить ссылку на внешний объект. Но вы должны использовать списки инициализаторов в конструкторе, а не прямое назначение. Или вы можете использовать 'std :: reference_wrapper'. Остерегайтесь хранения ссылок в объектах, потому что у вас могут быть проблемы с продолжительностью жизни объекта. – paddy
uhmn ... спасибо за «указатель». Я не знал о 'std :: move' или' std :: reference_wrapper'. Я прочитаю об этом. – TuanDT