具体问题:
我有一个Main应用程序,它包含A类和B类(以及其他类型)的对象。 类型B的对象需要正确构造一个对象(因此有一个构造函数 A(const B& b)。但是Main可以随时更改它保存的B对象。我该怎么做 确保当Main更改其B对象时,A对象的内部引用会更改吗?
一般来说,管理对象生命周期的一些好方法是什么? 有依赖吗?
答案 0 :(得分:3)
如果A
从不缓存任何B
属性,并且始终引用B
的实例,则生成任何相关输出,对B
所做的任何更改应该反映在随后的A
调用中。我假设您只是在构造函数中存储对B
的引用而不是创建本地副本。
答案 1 :(得分:1)
如果我理解正确,你不仅要改变B对象,而且要用不同的B替换它。一旦创建,就不能改变引用,所以你需要使用指针。
您可能希望使用观察者模式让A对象知道何时应该替换他们的B:http://en.wikipedia.org/wiki/Observer_pattern
答案 2 :(得分:0)
一般情况下:始终确保您了解所有权。无论何时创建对象,另一个对象都需要是所有者,或者它必须是局部变量。在你的情况下,主例程将是B实例的所有者。如果你在A实例中有对B的引用,A将看到对实例的所有更改 - 只是确保你不复制(没有引用吗?隐式复制)。因此,在您的代码中,您将拥有类似
的内容private:
const B& theReference;
或
private:
B& theReference;
如果你需要调用非const方法(在这种情况下还记得改变你的构造函数)。
答案 3 :(得分:0)
如果我理解正确,如果你对主要持有的对象进行修改,它应该反过来影响A
所持有的对象。为此,您可以使用构造函数初始化程序。
#include <iostream>
class B{
public:
int num ;
B(int arg):num(arg) {}
};
class A{
public:
const B& ref ;
A( const B& arg ): ref(arg){}
};
int main()
{
B objOne(10) ;
A objTwo(objOne) ;
std::cout << objTwo.ref.num << std::endl ;
objOne.num = 20 ;
std::cout << objTwo.ref.num << std::endl ;
}
输出
10
20
答案 4 :(得分:0)
请记住:
在您的情况下,如果B
实例可以随时出现(旧实例被删除,新实例被“新建”),那么您可以创建一个“实用程序句柄”类“包装”B
实例:
class BHandle {
B* b_; // can change at any time
public:
....
};
然后,您的A
类将引用BHandle
实例,或完全包含BHandle
实例。然后,B
个实例可以来去,但A::my_b_handle_
将始终反映“当前”B
实例所在的位置。
另一方面,如果B
实例仅包含更改的数据成员(其实例本身不是来去),那么您不需要执行任何操作(A
将始终引用相同的B
实例,在某些情况下,您可能只需要“通知”A
在其引用的B
对象中更改的属性。
答案 5 :(得分:0)
以下是我处理问题的方法。用户代码如下所示:
class Env
{
public:
Env();
~Env();
private:
void *priv;
};
class MyInterface
{
public:
MyInterface(Env &e) : e(e) { }
int create_A();
void use_A(int a);
private:
Env &e;
void *priv;
};
int main()
{
Env e;
MyInterface i(e);
int a = i.create_A();
use_A(a);
}
这样,每个依赖项都在用户代码中可见。对象之间的依赖关系很好地存储在Env类的std :: vectors中。将从函数返回向量的索引。 create_A()和use_A()可以通过int进行通信。当Env类超出范围时,对象将全部被销毁。您的对象可以从具有虚析构函数的基类派生。
如果你有多个int,推荐的方法是:
struct ID { int i; };
接口的实现将依赖于以下功能:
A *find_a(const Env &e, ID i);
ID create_a(Env &e, A *ptr);
上述方法解决了对象生存期的以下问题: