如果构造函数参数与 C++ 中的成员变量同名怎么办?

Posted

技术标签:

【中文标题】如果构造函数参数与 C++ 中的成员变量同名怎么办?【英文标题】:What if a constructor parameter has the same name as a member variable in C++? 【发布时间】:2010-02-09 06:33:34 【问题描述】:

先写一些代码:

class CInner 
public:
    CInner( const CInner& another )  //impl here 
private:
    // some member variables


class COuter 
public:
    COuter( const CInner& inner ) : inner( inner ) 
private:
    CInner inner;

是的,COuter::COuter( const CInner& ) 中的参数与成员变量同名。

在 VC++ 中有效 - VC++ 认为使用参数初始化成员变量是合理的,这就是发生的情况 - CInner::inner 使用参数初始化。但是当它用 GCC 编译时,它会以另一种方式解释:GCC 初始化 CInner::inner 用它自己,所以它没有初始化。

哪个编译器是对的?

【问题讨论】:

是什么让你觉得 gcc 会用自己初始化 inner 肯定有其他问题,我知道没有 GCC 版本有问题,而且它符合标准。顺便说一句,您的描述与您的代码不符 - 您谈论的是 CInner::inner,但代码中只有 COuter::inner 显示问题的示例将很有用。你如何确定inner是如何被初始化的? @sharptooth:嗯,我确实试过了,很容易看出在我的例子中一切都被正确初始化了。这就是为什么我要问有问题的案例应该是什么样子。 我以前用 GCC 做的,我只是用我目前使用的当前版本的 GCC 测试它。据我记得,它过去可以正常工作,现在也可以正常工作。您使用的是什么版本的 GCC? 【参考方案1】:

这并不是关于某些特定的编译器来决定什么是合理的,什么是不合理的。语言规范明确指出,在构造函数初始值设定项列表中使用的inner(inner) 中,第一个inner 应在类范围内查找(即解析为COuter::inner),而第二个inner 应在构造函数中查找范围(即解析为构造函数参数inner)。

这就是您所说的 VC++ 行为。但是,我很难相信 GCC 在这种情况下会表现不正确(除非你有一些奇怪的旧版本的 GCC)。你确定你没有以某种方式误解 GCC 的行为吗?

【讨论】:

这个问题可以通过简单地使用两个不同的变量名来避免。恕我直言,不同的名称也增加了可读性。【参考方案2】:

Visual C++ 是正确的。我怀疑您正在使用旧版本的 gcc 进行测试——至少我记得,最近的版本正确地做到了这一点。这在标准的 §12.6.2/7 中有介绍,其中给出了以下示例:

class X 

    int a;
    int b;
    int i;
    int j;

public:
    const int& r;

    X(int i): r(a), b(i), i(i), j(this->i) 

;

初始化X::r引用X::a,用构造函数的值初始化X::b 参数 i,用构造函数参数 i 的值初始化 X::i,[ ...]

【讨论】:

这可能是对的,但它非常丑陋,并且比需要的更难阅读。 @Craig:怎么会这样?我会说“难以阅读”是指您必须为概念上相同的对象跟踪两个不同的名称。当然,成员和构造函数参数应该具有相同的名称。它们应该是相同的。 我保持将私有成员变量保持为某种格式(例如 m_variable)的做法,我认为这是非常标准的,它可以避免这些冲突。我只是不认为有两个同名的变量是有意义的。即使一个是成员变量,一个是参数。每个人都有一个观点,他们认为事情变得太麻烦了,对我来说,在同一个函数中有两个同名的变量,加上 m_i(i) 比 i(i) 更容易概念化。

以上是关于如果构造函数参数与 C++ 中的成员变量同名怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

java中的this

C++基础6 继承 类型兼容 satatic 多继承 虚继承 多态 案例 虚析构函数 重载重写重定义

C++函数指针与成员函数指针

C++继承

C++继承

C++继承