2012-12-18 4 views
6

Nigdy wcześniej tego nie robiłem w C++, ale to dziwne, że nadal kompiluje, ale nie robi tego, czego się spodziewałem. Czy ktoś może mi powiedzieć, co robi? Proszę zobaczyć kod, więcej informacji poniżej.Tworzenie instancji klasy w C++: Dziwna składnia błędu

Będzie się kompilował, ale jeśli spróbuję użyć "t", nie będzie. Byłem zależny tylko od funkcji konstruktora, a mój kod nie działał zgodnie z oczekiwaniami. Rozwiązaniem jest utracenie nawiasu "Test t();" na "Test t;". Moje pytanie dotyczy tego, co dzieje się w "Test t();" na przykład, i co myśli kompilator, że pozwala na kompilację.

+5

Spójrz najbardziej podyktowane parse. – chris

+1

Witaj w swoim rytuale przejścia. –

+0

Pytanie brzmi ... czy kompilator wiedział, czego się spodziewałeś? :) – Carl

Odpowiedz

5

To jest Most Vexing Parse. Zasadniczo, zgodnie z regułami parsowania C++, to co tam masz nie jest obiektem typu Test o nazwie t, ale raczej deklaracją funkcji dla funkcji t, która przyjmuje zerowe argumenty i zwraca wartość Test.

Nawiasem mówiąc, clang ++ faktycznie rozpoznaje tę sytuację i wysyła ostrzeżenie, informując, że prawdopodobnie nie robi to, co chcesz.

+0

Czy możemy zadeklarować/zdefiniować funkcje w innych funkcjach? Zakładałem, że nie? –

+0

@KarthikT: Nie sądzę, że możesz zdefiniować funkcje zagnieżdżone w C++, ale z pewnością możesz je zadeklarować. Na przykład działa to dobrze: 'int main() {void foo(); bla(); } void foo() {std :: cout << "foo" << std :: endl; } ' –

+0

@Karthik: Funkcje mogą być * zadeklarowane * w innych funkcjach. Tak jest od kiedy C. – AnT

1

Jest to typowy problem, który został trafnie nazwany jako najbardziej irytujący parse . Twoja linia Test t(); może być interpretowana na jeden z dwóch sposobów.

  1. Można zadeklarować zmienną t który jest typu Test
  2. Można zadeklarować funkcję t(), która zwraca wartość Test i nie bierze argumenty

++ standard C niestety wymaga kompilatora rozważ drugą alternatywę, która jest dość irytującą parse.

Najłatwiej fix że analizować to, aby pozbyć się nawiasów i po prostu zadeklarować zmienną jako takie:

Test t; // Will call the default constructor