【问题标题】:(Beginner) C++ regarding inheritance(初级)关于继承的 C++
【发布时间】:2015-03-16 23:39:35
【问题描述】:

我正在尝试在 C++ 中解决一个关于继承的问题,并想知道如何正确地去做。

我设置了 3 个课程: - 敌人(有成员数据:int Damage、int Health 和 int Level) - 狼 - 熊

我的继承方式是:狼是敌人,熊是敌人。换句话说,Wolf 和 Bear 都继承自 Enemy。

我想设置我的程序,以便当我创建一个新的敌人时:

Enemy anEnemy; 

然后在 Enemy::Enemy() 构造函数中,它将随机决定该敌人是狼还是熊。

如何解决这个问题?我知道我必须在 Enemy::Enemy() 构造函数中生成一个随机数,并根据随机数的结果将敌人变成熊或狼。但我就是想不通如何将它(敌人)“变成”狼或熊。

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • “但我就是想不通如何将它(敌人)“变成”狼或熊。” 你不会“将”这些实例变成狼或熊,但首先将这些(狼/熊)实例化。查看std::unique_ptr<Enemy>std::shared_ptr<Enemy> 可以为您做什么。
  • 查找“工厂”设计模式。

标签: c++ inheritance


【解决方案1】:

要在运行时随机决定类型,那么为了类型安全,您实际上必须使用动态分配,例如

Enemy* p_enemy = random_enemy();

// Use p_enemy here, e.g. p_enemy->make_noises(), then:
delete p_enemy;

random_enemy 是一个类似的函数

auto random_enemy()
    -> Enemy*
{
    return (my_random_number() > 0.5? new Wolf : new Bear);
}

然而,正如您将发现的那样,手动 delete 在许多/大多数情况下很难正确使用。因此,通过使用诸如std::unique_ptrstd::shared_ptr 之类的智能指针来自动化 是很常见的。那么使用代码可能如下所示:

unique_ptr<Enemy> p_enemy = random_enemy();

// Use p_enemy here, e.g. p_enemy->make_noises(), then it auto-deletes.

还有类似的功能

auto random_enemy()
    -> unique_ptr<Enemy>
{
    return unique_ptr<Enemy>(
        my_random_number() > 0.5? new Wolf : new Bear
        );
}

【讨论】:

  • @anonymous downvoter:您应该始终解释您的反对意见。如果你不能解释投票,那么你应该投弃权票。
【解决方案2】:

你现在有两个问题:

首先,多态(查找)基于引用或指针,而不是值。 因此,当您创建 Ennemy(“随机”可能是熊或狼)时,您不能为其保存值类型的变量,因为类型并不总是相同的。

Ennemy my_ennemy = (Bear or Wolf); // This is impossible.

本质上,Bear 和 Wolf 不是同一类型,甚至大小也不相同,因此它们无法放入分配的 Ennemy 大小的内存量中。

你需要这些方面的东西:

Ennemy *my_ennemy = new Bear(); // OR
Bear someExistingBear;
Ennemy *my_ennemy = &someExistingBear; // Or even
std::unique_ptr<Ennemy> my_ennemy(new Bear());

相反,您必须决定是在 Ennemy 构造函数之外构建熊还是狼。

您可以像这样使用免费功能:

Ennemy *make_ennemy() {
     // Some random way to choose. Probably with a static seed.
    if (isbear)
        return new Bear();
    else
        return new Wolf();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 1970-01-01
    相关资源
    最近更新 更多