【问题标题】:Inherited class member with the same name as child constructor与子构造函数同名的继承类成员
【发布时间】:2019-08-05 07:02:17
【问题描述】:

考虑这个例子:

    class Label{
    public:
        std::string Text;    
    };

    class Text:
        public Label
    {
    public:
        Text(std::string text) {}
    };

    int main()
    {
        Text text("");
        text.Text; //<---- GCC CE: Invalid use of 'class Text'
        return 0;
    }
    class Text:
        public Label
    {
    public:
        Text(std::string text) {}
        using Label::Text; // doesn't help either
    };

如果继承的类成员与子类同名,如何访问它?

    class Text:
        public Label
    {
    public:
        Text(std::string text):
            Text::Text(Label::Text){}
        std::string &Text;
    };

这样的东西可以吗? (我知道上面的代码没有。)

【问题讨论】:

  • 没有nice 访问变量的方法。一种可能的解决方法是对此类变量使用“getters”和“setters”。
  • 顺便说一句:你有没有注意到Text 这个名字在那个代码示例中被过度使用了?如果您为正在处理的事情选择不同的名称,而不是解决您遇到的问题,也许它会有助于清晰。
  • 我正在实现包装器并尝试模仿现有元素的架构设计,当然名称相同。因此,如果在现有术语中,“Text”类型的元素是“Label”的子元素,并且“Label”中有“Text”属性 - 我无能为力。

标签: c++ inheritance gcc compiler-errors class-members


【解决方案1】:

这是一个变通方法(令人困惑);您可以通过基类名称访问基类的数据成员。例如

text.Label::Text;

【讨论】:

  • 谢谢。这肯定是一些奇怪的语法。请检查我有问题的更新吗?
  • @AlexanderG。我查了一下,好像是不可能的。在使用它之前,您不能拥有与该类同名的数据成员。 wandbox.org/permlink/dMdTuCVHYNPRkywx
【解决方案2】:

尽管正确答案是(@songyuanyao 发表)

text.Label::Text;

我已经想出了如何避免这种奇怪的语法。

使用旧的 C 风格 typedef 进行简单的“破解”即可:

    typedef class Text_:
        public Label
    {
    public:
        Text_(std::string text){}
    }Text;

现在突然代码示例编译了。 ...C++ 魔法...

【讨论】:

  • 无需使用 C 语法:class Text_ : public Label {/*..*/}; using Text = Text_;,您确实可以使用不同的名称解决问题,并且别名确实与该参数具有相同的名称,但不在同一范围内。
  • 其实和...完全没有区别。除了“使用”不适用于 C++98 和 C++03。
  • 好的。我应该举一个讽刺标志或类似的东西。 =)
猜你喜欢
  • 2015-03-21
  • 2013-05-07
  • 2012-10-16
  • 2011-06-20
  • 1970-01-01
  • 1970-01-01
  • 2013-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多