簡體   English   中英

如何根據構造函數參數使用超類類型初始化成員變量?

[英]How to initialize member variable with super class type depending on constructor argument?

經過幾個小時的搜索,我到了這里。 我有一個容器類,其中有一個指向基類的指針作為成員變量。 這應該引用Spec1或Base的另一個繼承的類,在此將其省略。 類型應由構造函數中的參數確定(例如,字符串,枚舉,整數等)。

我了解了很多有關動態內存分配的知識,以及為什么應盡可能避免使用它。 有可能避免在這里嗎? 構造函數之后是否會銷毀任何普通對象? 還是設計思路完全錯誤? 我來自Java :(預先感謝。

class Base{
  public:
    virtual ~Base(){}; // required?
    virtual void doSomething() = 0;
};

class Spec1 : public Base {
     public:
       Spec1(){};
       Spec1(int i){
         // whatever
       }
       void doSomething(){
          std::printf("hello world");
       }
};

class Container{
   public:
     Container(String type_message){
      if (type_message.compare("We need Spec1")){
          m_type = new Spec1(1);
      } // add more ifs for other types (Spec2, Spec3 etc.)
     }
     void doSomethingWithSpec(){
        m_type->doSomething();
     }
   private:
      Base* m_type;
 };

int main (int argc, char **argv){
    Container a ("We need Spec1");
    a.doSomething();
}

要求Container知道Base的每個可能派生類聽起來都不是一個好的設計。 那就是工廠功能的目的。

Container將該對象存儲為std::unique_ptr以避免內存泄漏和手動內存管理。

struct Base {
    virtual ~Base() = default;
    virtual void doSomething() = 0;
};

struct Spec1 : Base {
    void doSomething() override {
        std::printf("%s\n", __PRETTY_FUNCTION__);
    }
};

// Factory function.
std::unique_ptr<Base> createBase(std::string const& type) {
    if(type == "Spec1")
        return std::unique_ptr<Base>(new Spec1);
    throw std::runtime_error("Unknown type " + type);
}

class Container {
    std::unique_ptr<Base> m_type;
public:
    Container(std::string const& type)
        : m_type(createBase(type))
    {}

    void doSomething(){
        m_type->doSomething();
    }
};

int main() {
    Container a ("Spec1");
    a.doSomething();
}

構造函數的工作原理與其他任何函數一樣。 局部變量在函數完成時在堆棧中分配,並且超出范圍,而動態內存分配在堆棧中完成,並且需要在函數完成之前明確地釋放(在C ++中而不在Java中)。

但是你的情況

m_type = new Spec1(1);

new Spec1(1)在堆中動態分配,並且不會在構造函數代碼完成時被銷毀。 引用存儲在類的成員變量中。 因此,只要類Container的實例在范圍內,就Spec1(1)分配給Spec1(1)的內存。

要進行比較,只需考慮其他情況。

Container(String type_message){
      Base* m_type;
      if (type_message.compare("We need Spec1")){
          m_type = new Spec1(1);
      } // add more ifs for other types (Spec2, Spec3 etc.)
     }

在這里,一旦構造函數完成, m_type將超出范圍,但是隨着內存泄漏, new Spec1(1)仍將存在於堆中。

暫無
暫無

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

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