C ++覆盖成员变量

时间:2016-06-22 18:50:55

标签: c++ inheritance

这可能是一个愚蠢的问题,但我想知道是否有可能覆盖成员变量的类型,只要它是子类型。

基本上我有一个父类A,它有一个像这样的变量:

TSubclassOf<AItem> ItemClass;

然后在B类中扩展了A类,我想知道我是否可以将类型更改为不同的类型:

TSubclassOf<AWeapon> ItemClass;

其中Weapon扩展Item,因此它仍然是Item的子类。

这可能吗?

如果没有,是否可以隐藏子类中的变量?即我可以隐藏ItemClass并创建一个名为WeaponClass的新变量。

提前感谢您的帮助

2 个答案:

答案 0 :(得分:3)

通过在派生类中声明TSubclassof<AWeapon> ItemClass;,您基本上将ItemClass隐藏在基类中。所以,它看起来像你已经改变了#34;类型,但你没有,只有在派生类中你会看到新的类型变量。

如果你调用访问ItemClass的基类的成员函数,它将使用&#34; old&#34;类型变量。

  

如果没有,是否可以隐藏子类中的变量?即我可以隐藏ItemClass并创建一个名为WeaponClass的新变量。

可以,您可以将ItemClass声明为private变量,以便派生类无法访问它。然后,当您可以创建WeaponClass时,派生类中没有ItemClass

答案 1 :(得分:2)

在可见度方面,这取决于许多事情。如果ItemClassprivate,则类B甚至不会首先看到它,因此命名冲突无论如何都是不可能的。如果它是protected,那么...事情变得有点复杂。它不会抛出任何错误,但你会在子类中隐藏名称,但不会在超类中隐藏。看到这段代码作为例子:

#include <iostream>
#include <string>

struct message {
    std::string the_message;
    message() : the_message("default string") {}
    message(std::string a) : the_message(a) {}
    virtual ~message() = default;

    virtual void foo() { std::cout << the_message << std::endl; }
};

struct message_sub : message {
    int the_message;

    message_sub(int a) : the_message(a) {}
};

int main(int, char**) {
    message *a_message = new message_sub(12);
    a_message->foo();
    delete a_message;
}

Try it online

正如您所看到的,如果您运行它,输出不是12,正如您所料,default string。那是因为超类方法foo会在范围内看到事物;即它会看到你的名字隐藏在子类中的版本。解决此问题的唯一方法是将foo复制并粘贴到子类中,如果子类中不是virtual,则无法使其工作。

因此,我会建议不要你在这里做什么;您不能编写使用子类成员变量的默认实现,只能编写超类中存在的实现变量。具有相同名称但不同类型的两个变量是不同的变量。如果这只是想知道你是否可以安全地命名任何你想要的东西,是的,你可以,特别是如果它们是private