在dynamic_pointer_cast之后调用派生类的构造函数

时间:2018-09-13 17:27:39

标签: c++ c++11 casting polymorphism factory

我正在尝试实现字符工厂,但是我不明白如何为虚拟基类创建通用的shared_ptr,然后将其转换为带有构造函数中参数的派生类。 在我的示例中,我的虚拟基类无法在构造函数中接受参数,但在派生类的构造函数中需要它们。

std::shared_ptr<Character> CharacterFactory::createCharacter(Character::Type type, Character::SubType subtype, const TextureHolder &textures, sf::Vector2u windowSize) {

    std::shared_ptr<Character> character;

    if ( type == Character::enemy ) {
        std::dynamic_pointer_cast<Enemy>(character)(subType, textures, windowSize);

    } else if(type == Character::player) {
        //cast to player ...
    }

    return character;

可能是设计问题,我无法解决。如果可以的话,我不能使用原始指针

character = new Enemy(...);

会工作的。我发现用于铸造的所有示例都使用默认构造函数。

谢谢您的帮助

1 个答案:

答案 0 :(得分:5)

您不应该在这里投射。在if-else链中,您要做的是创建指向适当类型的共享指针,然后返回该shared_ptr。就像您拥有时一样,它将自动转换为std::shared_ptr<Character>

Character * character = new Enemy(...);

这意味着您的函数应类似于

std::shared_ptr<Character> CharacterFactory::createCharacter(Character::Type type, Character::SubType subtype, const TextureHolder &textures, sf::Vector2u windowSize) {    
    if ( type == Character::enemy ) {
        return std::make_shared<Enemy>(subType, textures, windowSize);
    } else if(type == Character::player) {
        return std::make_shared<Player>(subType, textures, windowSize);
    } 
    return {}; // return null on bad type
}

我们可以对上面的代码进行几周的测试,以提高其性能,并且如果工厂通过了错误的type,则不只是默默地返回空指针。为此,我们将使用std::unique_ptr并在type错误的情况下抛出异常。 std_unique_ptr可以转换为std::shared_ptr,因此默认情况下,这可使您的工厂使用两种类型的智能指针。这给了我们

std::unique_ptr<Character> CharacterFactory::createCharacter(Character::Type type, Character::SubType subtype, const TextureHolder &textures, sf::Vector2u windowSize) {    
    if ( type == Character::enemy ) {
        return std::make_unique<Enemy>(subType, textures, windowSize);
    } else if(type == Character::player) {
        return std::make_unique<Player>(subType, textures, windowSize);
    } 
    throw std::runtime_error("bad type passed to factory");
}