2009-05-18 13 views
321

Mam klasy z dwoma konstruktorami, jeden, który nie przyjmuje argumentów i jeden, który ma jeden argument.błąd: żądanie dla członka ".." w "..", który jest typu nieklasy

Tworzenie obiektów przy użyciu konstruktora, który przyjmuje jeden argument, działa zgodnie z oczekiwaniami. Jeśli jednak utworzę obiekty przy użyciu konstruktora, który nie przyjmuje argumentów, pojawia się błąd.

Na przykład, jeśli mogę skompilować ten kod (za pomocą g ++ 4.0.1) ...

class Foo 
{ 
    public: 
    Foo() {}; 
    Foo(int a) {}; 
    void bar() {}; 
}; 

int main() 
{ 
    // this works... 
    Foo foo1(1); 
    foo1.bar(); 

    // this does not... 
    Foo foo2(); 
    foo2.bar(); 

    return 0; 
} 

... pojawia się następujący błąd:

nonclass.cpp: In function ‘int main(int, const char**)’: 
nonclass.cpp:17: error: request for member ‘bar’ in ‘foo2’, which is of non-class type ‘Foo()()’ 

dlaczego jest to, i jak mogę to sprawić?

+0

pokrewne: http://stackoverflow.com/q/2318650/69537 – Meysam

Odpowiedz

501
Foo foo2(); 

zmiana

Foo foo2; 

Otrzymasz błąd, ponieważ kompilator myśli

Foo foo2() 

jak deklaracja funkcji o nazwie 'foo2' i zwracanego typu 'foo'.

Ale w takim przypadku Jeśli zmienimy na Foo foo2, kompilator może wyświetlić błąd " call of overloaded ‘Foo()’ is ambiguous".

+0

Nie rozumiem dlaczego kompilator myśli: Foo foo2() w deklaracji funkcji, wewnątrz głównej funkcji. –

+0

Najwyraźniej wylądowałem na tej odpowiedzi, ponieważ nie mogę ponownie jej głosować! Oto tekstowy 2-gie uptoote ... i drugie dzięki! – bigjosh

+0

Deklaracja funkcji bez parametrów powinna mieć przypisany parametr "void", aby użycie to było dozwolone z punktu widzenia spójności. Jeśli się nie mylę, K & R C miał obowiązkowe stosowanie terminu "pustka". – Rajesh

36

Tylko dla porządku ..

To nie jest rzeczywiście rozwiązaniem kodzie, ale miałem ten sam komunikat o błędzie, gdy nieprawidłowo dostępem metodę instancji klasy wskazywanego przez myPointerToClass, np

MyClass* myPointerToClass = new MyClass(); 
myPointerToClass.aMethodOfThatClass(); 

gdzie

myPointerToClass->aMethodOfThatClass(); 

byłoby oczywiście prawidłowe.

9

Dodanie do bazy wiedzy, mam ten sam błąd na

if(class_iter->num == *int_iter) 

Choć IDE dał mi poprawnych członków do class_iter. Oczywiście problem polega na tym, że "anything"::iterator nie ma członka o nazwie num, więc muszę go usunąć. Które nie działa tak:

if(*class_iter->num == *int_iter) 

... podobno. I ostatecznie rozwiązany z tym:

if((*class_iter)->num == *int_iter) 

Mam nadzieję, że to pomoże komuś, kto biegnie to pytanie tak zrobiłem.

+0

dzięki! pomógł mi w przypadku na wskaźniki do członka – nithin

+0

Dzięki, ja też miałem ten sam problem ze wskaźnikiem –

4

Miałem podobny błąd, wydaje się, że kompilator źle zrozumiał wywołanie konstruktora bez argumentów.Zrobiłem to działa poprzez usunięcie nawiasu od deklaracji zmiennej, w kodzie coś takiego:

class Foo 
{ 
    public: 
    Foo() {}; 
    Foo(int a) {}; 
    void bar() {}; 
}; 

int main() 
{ 
    // this works... 
    Foo foo1(1); 
    foo1.bar(); 

    // this does not... 
    Foo foo2; // Without "()" 
    foo2.bar(); 

    return 0; 
} 
+0

Jest to ta sama odpowiedź co [powyższa] (http://stackoverflow.com/questions/877523/error-request-for-member -in-który-jest-z-klasy-typu-# answer-877538) – Greenonline

+1

[Najbardziej irytujący parse] (https://en.wikipedia.org/wiki/Most_vexing_parse) nie jest tak źle, że kompilator źle zrozumiał , ponieważ jest to, że standard wymaga od kompilatora interpretacji wszystkiego, co może być deklaracją funkcji jako deklaracji funkcji, w celu uniknięcia niejasności. –

+0

(W szczególności pomiędzy ['[stmt.ambig/1]'] (https://timsong-cpp.github.io/cppwp/n4140/stmt.ambig#1) i ['[dcl.ambig.res/1 ] '] (https://timsong-cpp.github.io/cppwp/n4140/dcl.ambig.res#1), norma wyraźnie stwierdza, że ​​w przypadku niejasności wszystko, co może być interpretowane jako deklaracja, jest deklaracją , aby rozwiązać tę niejednoznaczność.) –

3

Parenthesis nie jest zobowiązany do wystąpienia obiektu klasy, jeśli nie zamierzasz używać parametryzowane konstruktora.

Po prostu użyj Foo foo2;

To zadziała.

0

wpadłem w przypadku, gdy dostałem ten komunikat o błędzie i miał

Foo foo(Bar()); 

i był w zasadzie stara się przekazać w tymczasowym Bar obiektu do konstruktora Foo. Okazuje się, że kompilator tłumaczył to

Foo foo(Bar(*)()); 

to jest deklaracja funkcji, którego nazwa jest foo, która zwraca Foo, które odbywają się w kłótnię - wskaźnik funkcji przekazujących bar z 0 argumentów. Podczas przechodzenia w takich tymczasowych, lepiej użyć Bar{} zamiast Bar(), aby wyeliminować niejednoznaczność.

-1

Dodanie mój błąd, próbowałem:

Foo.low[i]

Zamiast:

Foo[i].low

0

Jeśli chcesz zadeklarować nową substancję bez parametru (wiedząc, że obiekt mieć domyślne parametry) nie pisz

type substance1(); 

ale

type substance; 
Powiązane problemy