我正在尝试编写两个类A
和B
,其中B
包含类A
的实例。实际上,A
包含一些大数据。在这个玩具示例中,我们假设它们如下:
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)
如果我们使用B :: B(),创建一个空的,默认的A
对象?我试过了
B::B(A& a){
&ba = &a;
}
但它给出“左值必须在赋值左侧”错误。
任何建议表示赞赏。对不起这篇文章太长了。
答案 0 :(得分:2)
使用移动语义定义构造函数,如下所示:
B::B( A && a )
: ba( std::move( a ) )
{}
现在您可以将实例传输到对象中。
A a;
B b( std::move( a ) );
// `b` stores content of `a`, and local `a` is no longer valid.
如果您想要,您仍然可以使用复制构造函数进行构建。
A a;
B b( a );
// `b` stores a copy of `a`, and local `a` is still valid.
答案 1 :(得分:1)
不是将A作为简单成员var,而是使用指向A的指针。然后在构造B时,只需将指针传递给A的实例。
class B{
private:
A* ba;
答案 2 :(得分:1)
这取决于您的设计。如果您希望B
拥有A
std::move
,请A
获取B
。
一般情况下,使用std::shared_ptr
来管理内存。在std::shared_ptr<A>
的所有实例都将被销毁后,A
数据也将被删除。但在这种情况下,B
个实例可以共享相同的A
数据。
其他解决方案是std::unique_ptr
,但每次复制B
时都必须移动它,这意味着A
的所有权将与std::move
解决方案一样转移。