C++初始化包含另一个对象设计问题的对象

C++ initializing an object that contains another object design issue

本文关键字:问题 对象 初始化 包含另 一个对象 C++      更新时间:2023-10-16

我正在尝试编写两个类AB,其中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(A& a)初始化B时,参数被复制到实例中,baB中。如果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的内存。

如果我们使用B::B(A& a),是否有一种方便的方法可以将对象A(在B之外创建)的"引用"传递到构造函数中的B中,如果我们使用 B::B(),则创建一个空的默认A对象?我试过了

B::B(A& a){
&ba = &a;
}

但它给出了"左值必须在分配的左侧"错误。

任何建议不胜感激。对不起,帖子太长了。

使用移动语义定义构造函数,如下所示:

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.

不要将 A 作为简单的成员 var,而是有一个指向 A 的指针。然后在构造 B 时,只需传递指向 A 实例的指针。

class B{
private:
A* ba;

这取决于你的设计。如果您想B自己的A请使用std::move通过B获得A

在一般情况下,使用std::shared_ptr它将自行管理内存。销毁std::shared_ptr<A>的所有实例后,A数据也将被删除。但在这种情况下,B实例可以共享相同的A数据。

其他解决方案是std::unique_ptr但每次复制时都必须移动它B这意味着A的所有权将与std::move解决方案一样转移。