如果构造函数参数与c++中的成员变量具有相同的名称,该怎么办?

时间:2022-11-10 16:46:00

Some code first:

一些代码:

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;
}

Yes, in COuter::COuter( const CInner& ) the parameter has the same name as the member variable.

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

In VC++ that works - VC++ gets the idea that it is only reasonable to initialize the member variable with the parameter and that's what happens - CInner::inner gets initialized with the parameter. But when the same is compiled with GCC it is interpreted in another way: GCC initializes CInner::inner with itself and so it is left uninitialized.

在vc++中,VC++ +认为只有用参数初始化成员变量才是合理的,这就是发生的情况——CInner::inner用参数初始化。但是当与GCC一起编译时,它会以另一种方式解释:GCC初始化CInner::内部本身,所以它是未初始化的。

Which of the compilers is right?

哪个编译器是正确的?

2 个解决方案

#1


25  

It is not really about some specific compiler deciding what's reasonable and what's not. The language specification explicitly says that in inner(inner) used in the constructors initializer list the first inner should be looked up in class scope (i.e. resolve to COuter::inner), while the second innershould be looked up in the constructor scope (i.e. resolve to constructor parameter inner).

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

This is what you described as VC++ behavior. However, I find it hard to believe that GCC would behave incorrectly in this case (unless you have some weird old version of GCC). Are you sure you haven't misinterpreted GCC's behavior somehow?

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

#2


12  

Visual C++ is correct. I suspect you're using an older version of gcc for your test -- at least as I recall, recent ones do this correctly. This is covered in §12.6.2/7 of the standard, which gives the following example:

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) {}

};

initializes X::r to refer to X::a, initializes X::b with the value of the constructor parameter i, initializes X::i with the value of the constructor parameter i, [ ...]

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

#1


25  

It is not really about some specific compiler deciding what's reasonable and what's not. The language specification explicitly says that in inner(inner) used in the constructors initializer list the first inner should be looked up in class scope (i.e. resolve to COuter::inner), while the second innershould be looked up in the constructor scope (i.e. resolve to constructor parameter inner).

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

This is what you described as VC++ behavior. However, I find it hard to believe that GCC would behave incorrectly in this case (unless you have some weird old version of GCC). Are you sure you haven't misinterpreted GCC's behavior somehow?

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

#2


12  

Visual C++ is correct. I suspect you're using an older version of gcc for your test -- at least as I recall, recent ones do this correctly. This is covered in §12.6.2/7 of the standard, which gives the following example:

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) {}

};

initializes X::r to refer to X::a, initializes X::b with the value of the constructor parameter i, initializes X::i with the value of the constructor parameter i, [ ...]

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