问题 为什么在使用()用于声明对象时不调用构造函数? [重复]


可能重复:
为什么使用一组空括号来调用没有参数的构造函数是错误的? 

$ 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;。显然我错了。


6207
2018-02-26 07:45


起源



答案:


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

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

List x之间有什么区别;和列表x();


12
2018-02-26 07:47



@Lazer:说服自己,尝试使用m1(例如访问m1.m_count)... - Francesco
在C ++ 11中,您可以对所有构造函数调用使用大括号,这避免了c ++最令人头疼的解析,即Matrix m1 {}; - mark
这不是“最令人烦恼的解析”,最令人烦恼的解析是当你尝试声明和对象并将初始化临时值传递给它的一个或多个构造函数参数时。例如。 A b(A());。 Matrix m1(); 只是一个常规的函数声明。 - CB Bailey
@CharlesBailey:最令人烦恼的解析是关于如果可能的话将声明视为函数声明。这个问题确实只是另一个最令人烦恼的解决问题。 - Cheers and hth. - Alf


答案:


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

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

List x之间有什么区别;和列表x();


12
2018-02-26 07:47



@Lazer:说服自己,尝试使用m1(例如访问m1.m_count)... - Francesco
在C ++ 11中,您可以对所有构造函数调用使用大括号,这避免了c ++最令人头疼的解析,即Matrix m1 {}; - mark
这不是“最令人烦恼的解析”,最令人烦恼的解析是当你尝试声明和对象并将初始化临时值传递给它的一个或多个构造函数参数时。例如。 A b(A());。 Matrix m1(); 只是一个常规的函数声明。 - CB Bailey
@CharlesBailey:最令人烦恼的解析是关于如果可能的话将声明视为函数声明。这个问题确实只是另一个最令人烦恼的解决问题。 - Cheers and hth. - Alf


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()'


3
2018-02-26 07:51





从C语言的角度思考:

int data_member();

实际上是一个函数的原型,它取出了void并返回int。当你改变它时:

T data();

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

T data; // int data;

1
2018-02-26 09:00





这将做你想做的事情:

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

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


0
2018-02-26 08:34