【问题标题】:Base constructor calls derived constructor depending on input - Choose object sub-type at runtime基础构造函数根据输入调用派生构造函数 - 在运行时选择对象子类型
【发布时间】:2020-05-19 01:59:32
【问题描述】:

假设我有一个 Human 类:

class Human {
public:
    bool isFemale;
    double height;
    Human(bool isFemale, double height) {
        this->isFemale = isFemale;
        this->height = height;
    }
};

以及实现自己的方法的派生类,例如女性和男性。在 C++11 中,我是否有办法在运行时根据 Human 构造函数的输入来确定 Human 应该是哪个“子类型”(男性或女性)? 我在各自的班级中为男性和女性设置了不同的行为。我要做的是在运行时确定 Human 是女性类型还是男性类型,具体取决于构造函数输入,因此我可以(之后)根据其类型应用适当的行为。 理想的情况是始终调用 Human 构造函数,并在运行时选择适当的子类型,具体取决于在构造函数中输入的参数。如果可能的话,我想应该扭曲“人类”构造函数,但我不确定如何......

【问题讨论】:

  • 您已经在运行时分配了isFemale
  • 我将此属性分配给 Human;现在我想知道基于此属性的对象类型是否可以是“女性”(即根据基于构造函数参数的调度对象类型)。之后的目标是根据适当的子类型调用 Human 上的所有适当方法,而不必使用 (if (isFemale...)... if(!isFemale...))。 (添加到帖子中)
  • 您在寻找工厂设计模式吗?
  • 你为什么要这样做?如果你想要男性和女性的不同行为,你应该把它放在各自的类中。
  • Human的构造函数只能创建一个Human(即使是某个派生类的Human子对象)。您正在寻找的可能是工厂功能。

标签: c++ oop c++11 design-patterns factory


【解决方案1】:

通过调用Human的构造函数,只能创建Human对象。

据我了解,您希望根据运行时获得的性别输入创建 MaleFemale 对象。然后,您可能应该考虑使用 工厂函数 来实现此目的。

例如,如果您将MaleFemale 定义为:

struct Male: public Human {
   Male(double height): Human(false, height) {}
   // ...
};

struct Female: public Human {
   Female(double height): Human(true, height) {}
   // ...
};

然后,您可以使用以下工厂函数,make_human()

std::unique_ptr<Human> make_human(bool isFemale, double height) { 
   if (isFemale)
      return std::make_unique<Female>(height);
   return std::make_unique<Male>(height);
}

它在运行时根据传递给isFemale 参数的参数决定是创建Female 还是Male 对象。

请记住让Human 的析构函数virtual 因为MaleFemale公开 继承自Human

【讨论】:

    【解决方案2】:

    请注意,您的设计允许 MaleisFemale = "true",您可以在内部委派此操作以避免错误标志,出于示例目的,您可以执行以下操作:Live Sample

    #include <iostream>
    
    class Human {
    private:
        int height;
    
    protected:
        bool isFemale;
    
    public:
        Human(){};
        Human(int height, bool isFemale = false) : height(height) {}
        virtual ~Human(){}
    };
    
    class Female : public Human {
    public:
        Female(int height) : Human(height, true) {
            std::cout << "I'm a new Female, my height is " << height << std::endl;
        }
    };
    
    class Male : public Human {
    public:
        Male(int height) : Human(height, false) {
            std::cout << "I'm a new Male, my height is " << height << std::endl;
        }
    };
    

    您可以调用适当的构造函数,例如:

    int main() {
    
        char gender;
        Human h;
    
        std::cout << " enter m/f: ";
        std::cin >> gender;
    
        switch(gender){
            case 'm':
            case 'M':
              h = Male(186);
                break;
            case 'f':
            case 'F':  
              h = Female(175);
              break;
        }
    }
    

    如果您想利用多态性,请查看this thread

    【讨论】:

    • @idclev463035818 这就是 OP 想要的。对我来说,我只是在内部定义它。
    • 是的,这不是一个很好的设计,但是如果您注意到,在接受的答案中他对此感到满意,我将更改我的答案以提供替代方案。
    猜你喜欢
    • 2022-12-03
    • 2018-07-21
    • 2016-07-19
    • 1970-01-01
    • 2015-08-18
    • 2018-07-16
    • 1970-01-01
    • 2014-11-17
    • 2020-11-28
    相关资源
    最近更新 更多