为什么在使用()用于声明对象时不调用构造函数?

时间:2012-02-26 07:45:47

标签: c++ constructor most-vexing-parse

  

可能重复:
  Why is it an error to use an empty set of brackets to call a constructor with no arguments?

$ cat cons.cpp
#include <iostream>

class Matrix {
private:
    int m_count;

public:
    Matrix() {
        m_count = 1;
        std::cout << "yahoo!" << std::endl;
    }
};

int main() {
    std::cout << "before" << std::endl;
    Matrix m1();                         // <----
    std::cout << "after" << std::endl;
}
$ g++ cons.cpp
$ ./a.out
before
after
$

语法Matrix m1();的作用是什么?

我认为它与Matrix m1;相同。显然我错了。

4 个答案:

答案 0 :(得分:12)

Matrix m1(); // m1 is a function whose return type is Matrix.

此C ++ FAQ lite条目也应该有用。

Is there any difference between List x; and List x();

答案 1 :(得分:3)

Matrix m1()声明一个不带参数的函数并返回Matrix。你可以通过向Matrix添加方法并尝试在m1上调用它来看到这一点:

#include <iostream>

class Matrix {
private:
    int m_count;

public:
    Matrix() {
        m_count = 1;
        std::cout << "yahoo!" << std::endl;
    }
    void foo() {}
};

int main() {
    std::cout << "before" << std::endl;
    Matrix m1();
    m1.foo();
    std::cout << "after" << std::endl;
}

给出error: request for member 'foo' in 'm1', which is of non-class type 'Matrix()'

答案 2 :(得分:1)

从C语言角度思考:

int data_member();

实际上是函数获取void并返回int的原型。当你改变它时:

T data();

它仍然是一个函数声明,重新调整T。当您需要将其声明为变量时,您可以:

T data; // int data;

答案 3 :(得分:0)

这将做你想做的事情:

int main() {
    std::cout << "before" << std::endl;
    Matrix m1;                         // <----
    std::cout << "after" << std::endl;
}

在C ++中,如果使用parens初始化变量,它实际上声明了一个不带参数的函数并返回该类型。