Почему конструктор не вызывается, когда() используется для объявления объекта?

Возможный дубликат:
Почему это ошибка при использовании пустого набора скобок для вызова конструктора без аргументов?

$ 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;. Очевидно, я ошибаюсь.

Ответ 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;
}

В С++, если вы инициализируете переменную с помощью parens, она фактически объявляет функцию, которая не принимает никаких параметров и возвращает этот тип.