繁体   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