【问题标题】:call constructor of a derived class after a dynamic_pointer_cast在 dynamic_pointer_cast 之后调用派生类的构造函数
【发布时间】:2018-09-13 17:27:38
【问题描述】:

我正在尝试实现一个字符工厂,但我不明白如何为虚拟基类创建一个通用的 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(...);

本来可以的。我发现的所有转换示例都使用默认构造函数。

感谢您的帮助

【问题讨论】:

  • std::make_shared&lt;Enemy&gt;(...)
  • 构造函数不能被显式调用。它们是无名的,无法获取地址,也不是可以调用的函数。它们可能只会在创建新对象的过程中被隐式调用。您的构造似乎会尝试调用operator()
  • @FrançoisAndrieux:我认为您的意思是调用构造函数没有特殊语法。它们肯定可以被显式调用。只有在默认构造和转换的情况下才能隐式调用它们。然而,我记得与 James Kanze 就这个问题进行了长达数年的讨论。直到我说出 Bjarne Stroustrup 的一些名言,他才被说服。
  • @Cheersandhth.-Alf 这里可能有误会。我的意思并不是将隐式构造函数调用称为隐式转换中使用的那些调用。我的意思是那些通过创建新实例生成的调用。我也不认为构造对象是对构造函数的显式调用(即使将调用构造函数)。我的评论是说没有办法像调用函数一样调用构造函数。换句话说,创建对象不同于调用对象的构造函数。
  • @FrançoisAndrieux:好吧,T() 调用了T 默认构造函数,生成了一个T 对象。这对我来说“就像一个功能”。它是一个被调用的函数,它看起来像一个函数调用(尽管在语法上我认为它是一个类型转换表达式,但在语义上没有意义,但是)。总而言之,它长得像鸭子,叫起来像鸭子,蹒跚着像鸭子。

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


【解决方案1】:

你不应该在这里投射。在您的 if-else 链中,您所做的是创建一个指向适当类型的共享指针,然后返回该 shared_ptr。它会自动转换为std::shared_ptr&lt;Character&gt;,就像您在使用时一样

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
}

我们可以在上面应用几个 tweek 来提高性能,而不是在工厂传递一个错误的 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");
}

【讨论】:

    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 2014-11-17
    • 2015-05-28
    • 2016-07-19
    • 2012-11-06
    • 1970-01-01
    • 2018-07-21
    • 2018-07-16
    相关资源
    最近更新 更多