如果构造函数参数与 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++ 中的成员变量同名怎么办?的主要内容,如果未能解决你的问题,请参考以下文章