2012-01-13 4 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))    ); 

Я пытаюсь понять, почему приведенное выше не будет компилироваться. По какой-то причине, когда я пытаюсь создать экземпляр Rect2f (что унаследовать от Shape класс указан shared_ptr аргумент шаблона, так же, как Circle), я получаю следующее ошибки:Ошибка: ожидаемый тип-спецификатор до «ClassName»

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

Все о Circleshared_ptr - отлично. С этим нет никаких проблем; это только Rect2f, что вызывает проблемы.

Кроме того, значения, переданные в конструктор, действительны.

Итак, что может быть проблема с этим? У меня есть Rect.h для этого. Ради краткости (и упаковывают я пропустил что-то в этом файле, который может влиять на это), я выложу следующее:

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; 

}; 

Источник функции ошибки и заголовочный файл (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); 
} 

Основная функция Test (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(); 
} 

Вопрос

Судя по ошибкам, предоставленных, что я здесь отсутствует? Кроме того, что можно сделать, чтобы исправить эту проблему?

+0

Вы включили заголовок для Rect2f? Или вы сделали декларацию? –

+0

Да, я включил заголовок для Rect2f. – zeboidlund

ответ

6

Прежде всего, давайте попробуем сделать ваш код немного проще:

// 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()); 

Итак, теперь мы видим, что круглые скобки четко сбалансированы. Что еще это может быть? Давайте проверим following code snippet's error:

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

Это может показаться странным использование, и это, но я действительно ненавижу утечек памяти. Однако этот вывод представляется полезным:

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

Aha! Теперь мы просто оставили ошибку в круглых скобках. Я не могу найти причину этого; однако, я думаю, вы забываете включить файл, который определяет Rect2f.

+0

Итак, тогда Shape не найден? – zeboidlund

+0

Нет, 'Rect2f' не найден. Вам нужно «#include» Rect.h »' –

+0

Здесь я отправлю функцию (включая заголовок), откуда это происходит. Одно дело отметить, что у меня уже было '#include" Rect.h "' – zeboidlund

0

Из обсуждения с первого ответа: 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".

Похоже, вы пропустили эту функцию из вашего Rect2f класса:

virtual bool Intersects(const Circle& c) const;

+0

Все еще ничего ... Я реализовал это с мыслью, что это сработает и что MinGW просто глупо, но, к сожалению, ошибки все еще остаются. – zeboidlund

134

Для будущих людей борется с Аналогичная проблема заключается в том, что компилятор просто не может найти тип, который вы используете (даже если ваш Intelisense может его найти).

Это может быть вызвано несколькими способами:

  • Вы забыли #include заголовок, который определяет его.
  • Ваши защитные стражи (#ifndef BLAH_H) являются дефектными (ваш #ifndef BLAH_H не соответствует вашему #define BALH_H из-за ошибки печати или копирования + вставки).
  • Или, компилятор думает вы имели в виду одну область, когда на самом деле вы имели в виду другой (например, если у вас есть NamespaceA::NamespaceB, а <global scope>::NamespaceB, если вы уже в NamespaceA, это будет выглядеть в NamespaceA::NamespaceB и не беспокоиться о его проверке <global scope>::NamespaceB) если вы явно не обращаетесь к нему.

Для явного доступа что-то в глобальном пространстве имен, префикс с ::, как если глобальное пространство имен является пространством имен без имени (например, ::MyType или ::MyNamespace::MyType).

+5

Возможно, у вас также есть копия и вставка вашего защитника включения в другой файл заголовка без его изменения. – opyh

+1

Два 'exceptions.h' в отдельных подкаталогах; оба '#ifndef __ProjectName__exceptions_'; один включает другой. D'о! – OJFord

+0

Вот почему я установил clang для визуальной студии, поэтому я могу получать сообщения об ошибках, когда я в тупике. – Dan