[英]C++: How to manage object lifetimes and dependencies?
一個具體的問題:
我有一個主應用程序,它具有 A 類型和 B 類型(以及其他類型)的對象。 Object of type B requires A object to be properly constructed (so there is a constructor A(const B& b). However Main may change B object it holds at any time. How do I make sure that when Main changes its B object then the一個對象的內部引用被改變了?
一般來說,管理 object 生命周期的一些好的做法是什么,對象有依賴關系?
如果A
從不緩存任何B
屬性,並且始終引用它持有的B
的實例以生成任何依賴的 output,則對B
所做的任何更改都應反映在對A
的后續調用中。 我假設您只是在構造函數中存儲對B
的引用,而不是創建本地副本。
如果我理解正確,您不僅要更改 B object,還要用不同的 B 完全替換它。引用一旦創建就無法更改,因此您需要改用指針。
您可能希望使用觀察者模式讓 A 對象知道何時應該替換它們的 B: http://en.wikipedia.org/wiki/Observer_pattern
一般來說:始終確保您了解所有權。 每當您創建 object 時,另一個 object 必須是所有者,或者它必須是局部變量。 在您的情況下,主例程將是 B 實例的所有者。如果您在 A 實例中有對 B 的引用,A 將看到對實例的所有更改 - 只要確保您不復制(沒有引用確實隱式復制)。 所以在你的代碼中你會有類似的東西
private:
const B& theReference;
或者
private:
B& theReference;
如果您需要調用非常量方法(請記住在這種情況下還要更改您的構造函數)。
如果我理解正確,如果您對 main 持有的 object 進行修改,它應該反過來影響A
持有的 object。 為此,您可以借助構造函數初始化程序。
#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 ;
}
Output:
10
20
記住:
在您的情況下,如果B
實例可以隨時進出(舊實例被刪除,新實例被“新建”),那么您可以創建一個“實用程序句柄” class 來“包裝” B
實例:
class BHandle {
B* b_; // can change at any time
public:
....
};
然后,您的A
class 將引用BHandle
實例,或完全包含BHandle
實例。 然后, B
實例可以來來去去,但A::my_b_handle_
將始終反映“當前” B
實例的位置。
另一方面,如果B
實例僅具有更改的數據成員(它的實例本身不會來來去去),那么您不需要做任何事情( A
將始終引用相同的B
實例,並且您可以在某些情況下,只需要“通知” A
它引用的B
object 中的屬性發生了變化)。
這是我處理問題的方法。 用戶代碼如下所示:
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 class 中的 std::vectors 中。 向量的索引將從函數返回。 create_A() 和 use_A() 可以通過整數進行通信。 當 Env class 離開 scope 時,這些對象將同時被銷毀。 您的對象可能源自具有虛擬析構函數的基礎 class。
如果您有多個 int,推薦的方法是:
struct ID { int i; };
接口的實現將依賴於以下功能:
A *find_a(const Env &e, ID i);
ID create_a(Env &e, A *ptr);
上述方法解決了 object 生命周期的以下問題:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.