簡體   English   中英

具有參考的構造函數中的C ++ 11依賴注入

[英]C++11 dependency injection in constructor with reference

考慮以下代碼:

#include <stdio.h>
#include <memory>

class Sub{};

class SubImpl : public Sub {};

class A{
public:
    A(Sub & sub) : sub(sub){}

    void doSomething(){
        // ...
    };

private:
    Sub & sub;
};

std::unique_ptr<A> factory(){
    SubImpl sub;

    return std::unique_ptr<A>(new A(sub));
}

int main(){
    auto a = factory();

    a->doSomething();
}

此代碼有問題-子對象的生存期與A對象不同,並且A::sub引用懸空了。

為了解決這個問題,我可以做:

  • 傳值
  • 通過const引用傳遞
  • 使用unique_ptr / shared_ptr或使用原始指針

我還有其他方法可以解決此問題嗎?

如果object sub對象僅用於創建一個A對象,請使用unique_ptr 否則,請使用shared_ptr

class Sub{};

class SubImpl : public Sub {};

class A{
public:
    A(std::unique_ptr &&sub) : sub(std::move(sub)){}

    void doSomething(){
        // ...
    };

private:
    std::unique_ptr sub;
};

std::unique_ptr<A> factory(){
    auto sub = std::make_unique<SubImpl>();;

    return std::make_unique<A>(std::move(sub));
}

int main(){
    auto a = factory();

    a->doSomething();
}

看來您有兩種選擇,要么SubImpl的生存期由A控制,在這種情況下,我看不到使用指針(最好是unique_ptr替代方法,如bolov所示。 我認為這沒有什么特別的錯誤。

或者, SubImpl的生存期由A之外的其他項控制,在這種情況下,您可以使用引用。

例如,您可以更改工廠,使其成為擁有SubImpl的對象。 這是一個簡單的例子:

// definitions of Sub, SubImpl and A as before... 

class SubOwner {
    SubImpl sub;
public:
    A createA() const {
        return A(sub);
    }
};

int main(){
    SubOwner so;
    auto a = so.createA();
    a.doSomething();
} 

如果您只想要一個SubImpl ,那SubImpl但是您可能希望使用工廠創建許多A並且每個A應該引用一個不同的SubImpl 在這種情況下,您可以擁有一個擁有SubImpl集合的SubImpl

class SubOwner {

    // Using deque instead of vector to avoid reference invalidation. 
    // Could use vector if you knew how many SubImpl you need up front. 
    std::deque<SubImpl> subs;
public:
    A createA() const {
        subs.emplace_back();
        return A(subs.back());
    }
};

int main(){
    SubOwner so;
    auto a1 = so.createA();
    auto a2 = so.createA();

    a1.doSomething();
    a2.doSomething();
}

如果SubOwnerA本身屬於同一對象,或者屬於同一范圍的本地對象,則可以保證SubImpl的生存期與A相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM