2012-01-13 15 views
29
shared_ptr<Shape> circle(new Circle(Vec2f(0, 0), 0.1, Vec3f(1, 0, 0))); 

shared_ptr<Shape> rect(new Rect2f(Vec2f(0, 0), 5.0f, 5.0f, 0, 
            Vec3f(1.0f, 1.0f, 0))    ); 

Próbuję zrozumieć, dlaczego powyższe nie skompiluje. Z jakiegoś powodu, gdy próbuję utworzyć instancję Rect2f (która robi dziedziczą z klasy Shape podano argument shared_ptr szablonu, podobnie jak Circle), pojawia się następujący błędów:Błąd: oczekiwany specyfikator typu przed "ClassName"

error: expected type-specifier before 'Rect2f' 
error: expected ')' before 'Rect2f' 

Wszystko o Circleshared_ptr jest całkowicie w porządku. Nie ma z tym problemów; to tylko błąd Rect2f powoduje problemy.

Ponadto wartości przekazane do konstruktora są prawidłowe.

Jaki więc może być problem z tym? Mam do tego dołączone Rect.h. Przez wzgląd na zwięzłości (oraz okrywać brakowało mi coś w tym pliku, który może mieć wpływ na to), wyślę następujące:

Rect.h

#pragma once 

#include <QGLWidget> 
#include <GL/glext.h> 
#include <cmath> 
#include <QDebug> 
#include "Shape.h" 
#include "Vec3f.h" 
#include "rand.h" 

const int DEFAULT_SQUARE_WIDTH = 5; 
const int DEFAULT_SQUARE_HEIGHT = 5; 

typedef enum { 
    RC_TOPLEFT, 
    RC_TOPRIGHT, 
    RC_BOTTOMRIGHT, 
    RC_BOTTOMLEFT 
} RectangleCorner; 

class Rect2f : public Shape 
{ 
public: 

    Rect2f(
     Vec2f center = Vec2f(), 
     float width = 4, 
     float height = 4, 
     float radius = 0, 
     Vec3f color = Vec3f() 
    ); 

    ~Rect2f(); 

    inline const float GetWidth(void) const { 
     return mWidth; 
    } 

    inline const float GetHeight(void) const { 
     return mHeight; 
    } 

    inline const Vec2f* GetCorner(RectangleCorner rc) const { 
     switch(rc) { 
     case RC_TOPLEFT: 
      return mTopLeftCrnr; 
      break; 

     case RC_TOPRIGHT: 
      return mTopRightCrnr; 
      break; 

     case RC_BOTTOMLEFT: 
      return mBottomLeftCrnr; 
      break; 

     case RC_BOTTOMRIGHT: 
      return mBottomRightCrnr; 
      break; 
     } 
    } 

    void UpdateCorners(); 

    virtual void Collide(Shape &s); 

    virtual void Collide(Rect2f &r); 

    virtual void Collide (Circle &c); 

    virtual bool Intersects(const Shape& s) const; 

    virtual bool Intersects(const Rect2f& s) const; 

    virtual bool IsAlive(void) const; 

    virtual float Mass(void) const; 

protected: 

    virtual void Draw(void) const; 
    float mWidth, mHeight; 
    Vec3f mColor; 

private: 
    Vec2f* mTopLeftCrnr; 
    Vec2f* mTopRightCrnr; 
    Vec2f* mBottomLeftCrnr; 
    Vec2f* mBottomRightCrnr; 

}; 

Źródło funkcja błędu i plik nagłówkowy (mainwindow.cpp)

#include "ui_mainwindow.h" 
#include "Vec2f.h" 
#include "Rect2f.h" 
#include "SharedPtr.h" 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    BoxOfShapes* display = new InteractiveBoxOfShapes(this, 600, 600); 
    ui->mGridLayout->addWidget(display); 
    ui->mStatusBar->showMessage("status ok"); 

    QObject::connect(display, SIGNAL(numShapesChanged(int)), this, SLOT(setNumShapes(int))); 
    QObject::connect(ui->mResetButton, SIGNAL(pressed()), display, SLOT(resetWorld())); 
    shared_ptr<Shape> circle(
       new Circle(
        Vec2f(0, 0), 
        0.1, 
        Vec3f(1, 0, 0))); 
    /*std::shared_ptr<Shape> rect(<---error 
        new Rect2f(
         Vec2f(0, 0), 
         5.0f, 
         5.0f, 
         0, 
         Vec3f(1.0f, 1.0f, 0) 
        ) 
       );*/ 
    shared_ptr<Shape> rect(new Rect2f()); //error - second attempt 
    display->addShape(circle); 
    display->addShape(rect); 
} 

głównym badaniu funkcji (main.cpp)

#include <QtGui/QApplication> 
#include "mainwindow.h" 
#include "Rect2f.h" 

int main(int argc, char *argv[]) 
{ 
    Rect2f rec; 

    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 

Pytanie

Sądząc błędów usług, co ja tu brakuje? Co można zrobić, aby rozwiązać ten problem?

+0

Czy uwzględniłeś nagłówek Rect2f? A może złożyłeś deklarację terminową? –

+0

Tak, dodałem nagłówek Rect2f. – zeboidlund

Odpowiedz

6

Przede wszystkim spróbujmy uczynić kod trochę prościej:

// No need to create a circle unless it is clearly necessary to 
// demonstrate the problem 

// Your Rect2f defines a default constructor, so let's use it for simplicity. 
shared_ptr<Shape> rect(new Rect2f()); 

Ok, więc teraz widzimy, że nawiasy są wyraźnie zrównoważone. Cóż innego mogło być? Chodźmy sprawdzić following code snippet's error:

int main() { 
    delete new T(); 
} 

To może wydawać się dziwne użytkowania, a to jest, ale ja naprawdę nienawidzę wycieków pamięci. Jednak dane wyjściowe wydają się przydatne:

In function 'int main()': 
Line 2: error: expected type-specifier before 'T' 

Aha! Zostaje nam tylko błąd dotyczący nawiasów. Nie mogę znaleźć przyczyny tego; jednak myślę, że zapominasz dołączyć plik, który definiuje Rect2f.

+0

OK, więc Shape nie został znaleziony? – zeboidlund

+0

Nie, 'Rect2f' nie został znaleziony. Musisz "#include" Rect.h "' –

+0

Tutaj opublikuję funkcję (łącznie z nagłówkiem), skąd to pochodzi. Warto zauważyć, że już miałem '#include" Rect.h "' – zeboidlund

0

Z dyskusji z pierwszej odpowiedzi: http://chat.stackoverflow.com/rooms/6681/discussion-between-holland-and-anton-golov

Anton: It gives me the error "cannot allocate an object of abstract type ‘Rect2f’ because the >following virtual functions are pure within ‘Rect2f’: virtual bool Shape::Intersects(const >Circle&) const".

Wygląda na to, że brakuje tej funkcji z klasy Rect2f:

virtual bool Intersects(const Circle& c) const;

+0

Wciąż nic ... Wprowadziłem to z myślą, że to zadziała, a MinGW był po prostu głupi, ale niestety błędy nadal istnieją. – zeboidlund

134

Dla przyszłych ludzi zmaga się z podobny problem, sytuacja jest taka, że ​​kompilator po prostu nie może znaleźć typu, którego używasz (nawet jeśli twój Intelisense może go znaleźć).

Może to być spowodowane wieloma względami:

  • Zapomniałeś #include nagłówek, który definiuje je.
  • Twoje osłony (#ifndef BLAH_H) są uszkodzone (Twój #ifndef BLAH_H nie pasuje do Twojego #define BALH_H z powodu pomyłki literowej lub kopiowania + wklejania).
  • Albo kompilator myśli chodziło o jeden zakres, gdy naprawdę masz na myśli inny (na przykład, jeśli masz NamespaceA::NamespaceB, a <global scope>::NamespaceB, jeśli jesteś już w ciągu NamespaceA, to będzie wyglądać w NamespaceA::NamespaceB i nie przeszkadza sprawdzanie <global scope>::NamespaceB) chyba że wyraźnie uzyskasz do niego dostęp.

Aby jawnie dostęp do czegoś w globalnej przestrzeni nazw, poprzedzić je ::, jakby globalnej przestrzeni nazw jest nazw bez nazwy (np ::MyType lub ::MyNamespace::MyType).

+5

Możesz także skopiować i wkleić strażnika integracji do innego pliku nagłówkowego bez zmieniania go. – opyh

+1

Dwa 'exceptions.h' w oddzielnych podkatalogach; oba '#ifndef __ProjectName__exceptions_'; jedna obejmuje drugą. D'oh! – OJFord

+0

Właśnie dlatego zainstalowałem klang dla visual studio, dzięki czemu mogę uzyskać lepsze komunikaty o błędach, gdy jestem zakłopotany. – Dan

Powiązane problemy