【问题标题】:Why is the constructor not called when () is used to declare an object? [duplicate]为什么用()声明对象时不调用构造函数? [复制]
【发布时间】:2012-03-16 02:58:57
【问题描述】:

可能重复:
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;是一样的。显然我错了。

【问题讨论】:

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


    【解决方案1】:
    Matrix m1(); // m1 is a function whose return type is Matrix.
    

    这个 C++ FAQ lite 条目也应该很有帮助。

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

    【讨论】:

    • @Lazer:要说服自己,请尝试使用 m1 (例如访问 m1.m_count )...
    • 在 C++11 中,您可以对所有构造函数调用使用大括号,这避免了 c++ 最令人头疼的解析,即 Matrix m1{};
    • 这不是“最麻烦的解析”,最麻烦的解析是当您尝试声明和对象并将一个临时初始化的值传递给它的一个或多个构造函数参数时。例如。 A b(A());Matrix m1(); 只是一个普通的函数声明。
    • @CharlesBailey:最令人烦恼的解析是尽可能将声明视为函数声明。这个问题确实只是另一个最令人头疼的 Parse 问题。
    【解决方案2】:

    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】:

      从 C 语言的角度思考:

      int data_member();
      

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

      T data();
      

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

      T data; // int data;
      

      【讨论】:

        【解决方案4】:

        这会做你想做的事:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-02-18
          • 2014-01-14
          • 1970-01-01
          • 2018-07-03
          • 2019-11-05
          • 2021-02-26
          • 1970-01-01
          相关资源
          最近更新 更多