这怎么可能在c ++中使用?

时间:2013-10-08 14:33:03

标签: c++ class function-declaration variable-initialization

  1. 令我惊讶的是,我发现c ++对象的名称可以与类名相同。有人可以向我解释原因吗?
  2. 当我将类a的对象声明为a a1()时,它不会引发错误,但不会调用构造函数。为什么会这样?
  3. 我的代码:

    #include<iostream>
    using namespace std;
    
    class a 
    {
        public:
        a() 
        {
            cout << "in a\n";
        }
    };
    
    int main()
    {
        a a1();
        a a;
    }
    

5 个答案:

答案 0 :(得分:21)

当您编写a a1();时,它实际上被解析为函数声明而不是对默认构造函数的调用。

a a1;

将正确调用默认构造函数

当你编写a a;时它起作用,因为变量名在所谓的名称隐藏中优先于类名,但即使它起作用也只会导致混淆,我会避免这样做。

对于那些喜欢标准报价的人来说,你去

  

类名(9.1)或枚举名(7.2)可以通过在同一范围内声明的变量,数据成员,函数或枚举器的名称隐藏。如果类或枚举名称和变量,数据成员,函数或枚举器在同一作用域(按任何顺序)中声明具有相同名称,则类或枚举名称将隐藏在变量,数据成员,函数或枚举器名称可见。

答案 1 :(得分:8)

a a1();是一个函数声明。

这是在C ++ 11中创建统一初始化的重要原因。要使用C ++ 11中的构造函数初始化对象,请使用a a1{};

答案 2 :(得分:4)

如果您查看C++draft standard section 3.3.10 名称隐藏 2 说(强调我的):

  

类名(9.1)或枚举名称(7.2)可以通过在同一范围内声明的变量,数据成员,函数或枚举器的名称隐藏。如果类或枚举名称和变量,数据成员,函数或枚举器在同一作用域(按任何顺序)中声明具有相同名称,则类或枚举名称将隐藏在变量,数据成员,函数或枚举器名称是   可见。

我认为这不是一个好习惯,而且会导致难以维护代码。这行代码实际上是声明一个函数:

a a1();

您也可以使用此 C ++ 11

a a1 ;
C ++ 11 中引入了

uniform initialization

a a1{} ;

回到名字隐藏,我惊喜地看到clang会用此代码警告你这个问题,无论设置的警告级别如何:

int main()
{
   a a;
   a a2 ;
}

我收到此消息:

main.cpp:12:10: note: class 'a' is hidden by a non-type declaration of 'a' here
   a a;
     ^

虽然我看不到来自gcc的类似警告。

更新

考虑到我之前在warts of uniform initialization上发表的这一评论,我意识到,如果您怀疑a1某种程度上不是正确的类型,您可以使用typeid来调试正在发生的事情上。例如这段代码:

std::cout << typeid(a).name() << std::endl ;
std::cout << typeid(a1).name() << std::endl ;

会在Coliru live example上生成此输出:

1a
F1avE

并通过c++filt传递,您会收到此输出:

a ()     // A function that returns type a
a        // type a

答案 3 :(得分:0)

a a1();是一个函数声明返回类型为a,它与调用构造函数无关

a a ;是简单的语句,可以正常调用构造函数

答案 4 :(得分:0)

这是我在尝试使用clang编译代码时从代码中获得的内容,我认为它代表了所有内容。

test.cpp:15:9: warning: empty parentheses interpreted as a function declaration
      [-Wvexing-parse]
    a a1();
        ^~
test.cpp:15:9: note: remove parentheses to declare a variable
    a a1();
        ^~
1 warning generated.