【问题标题】:C++: Declaration of parameter hides class member even with "this" keywordC ++:即使使用“this”关键字,参数声明也会隐藏类成员
【发布时间】:2019-08-20 00:23:30
【问题描述】:

我最近开始使用“警告级别 4”,并在使用 C++ 编码时将警告视为错误。我想要一些关于以下 sn-p 的更深入的信息:

struct Foo
{
    Foo(int size)
        //:size{ size } // <- More on this later.
    {
        this->size = size;
    }

    void func(int size)
    {
        this->size = size;
    }

    int size;
};

int main()
{
    Foo a{ 1 };
    a.func(2);
}

所以,我从 Visual Studio 2019 收到以下警告/错误:

错误:C2220 - 警告被视为错误 - 未生成“对象”文件。

警告:C4458 - 'size' 的声明隐藏了类成员。

警告表明size 成员被方法的参数隐藏,该参数也名为size。输出表明错误不是来自构造函数,而是来自func 方法。我觉得这很令人困惑,因为构造函数似乎没有这个问题(实际上,删除 func 允许 sn-p 编译)。

降低警告级别允许应用程序编译,它似乎按预期工作。使用初始化列表而不是构造函数的主体(参见注释行)似乎也可以,但我猜这是由于初始化列表语义。

我知道错误表明funcsize 参数名称与Foo 的同名成员冲突,但this 关键字不应该解决这种混淆吗?这只是微软的编译器过于严格吗?

【问题讨论】:

  • 在构造函数的成员初始化列表中,:size{ size } 上没有警告,因为 size 是哪个没有歧义。左边的size 必须是类成员,右边的size 必须是输入参数。在没有显式使用 this-&gt; 的方法中,情况并非如此。

标签: c++ visual-c++ this compiler-warnings shadowing


【解决方案1】:

this 关键字不应该解决这种混乱吗?

并不是编译器对this-&gt;sizesize 不同感到困惑。即使删除该行,您也很可能会收到警告。编译器警告你函数的参数名称隐藏了成员名称。

【讨论】:

  • 如果我删除该行,我仍然会收到警告,但我不应该也收到来自构造函数的警告,因为它还有一个名为size 的参数吗?这似乎有点不一致。
  • @micka190,我同意它应该是一致的。我不知道为什么不是。
  • 有不同的编码风格。我现在发现抱怨构造函数参数名称会让太多人感到不安。
【解决方案2】:

在这个级别,这些警告是关于设置最佳实践的。确保您的成员变量名称与函数参数变量名称不同是一种很好的做法,可以使您的代码更具可读性。虽然“this->size”确实消除了歧义,但它也意味着当您在该函数中搜索 size 的使用时,您必须检查您所指的变量。使名称不同可以消除 2 个月后修复错误时的歧义 :) 推荐的修复方法包括将成员变量更改为具有前缀(例如 m_size),这也有利于改进自动完成/智能感知,或者更改参数名称。

我会注意到,作为错误的警告和 W4 是我强烈建议遵守的。好好照顾你的代码:)

【讨论】:

    猜你喜欢
    • 2014-08-05
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 2017-07-12
    • 2011-10-09
    • 1970-01-01
    相关资源
    最近更新 更多