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

Tôi đang cố gắng hiểu tại sao những điều trên sẽ không biên dịch. Vì lý do gì, khi tôi cố gắng tạo ra một thể hiện của Rect2f (mà không kế thừa từ lớp Shape quy định các shared_ptr mẫu đối số, giống như Circle), tôi nhận được sau lỗi:Lỗi: dự kiến ​​loại-specifier trước khi 'ClassName'

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

Tất cả mọi thứ về Circleshared_ptr hoàn toàn ổn. Không có vấn đề với nó; nó chỉ là Rect2f đang gây ra sự cố.

Hơn nữa, các giá trị được truyền vào hàm tạo là hợp lệ.

Vì vậy, vấn đề có thể xảy ra với vấn đề này là gì? Tôi có Rect.h bao gồm cho việc này. Vì lợi ích ngắn gọn của (và trong trường hợp tôi bị mất một cái gì đó trong tập tin đó mà có thể ảnh hưởng này), tôi sẽ đăng như sau:

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; 

}; 

Nguồn Lỗi Chức năng và tập tin tiêu đề (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); 
} 

Main Function 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(); 
} 

Câu hỏi

Đánh giá từ các lỗi được cung cấp, những gì tôi thiếu ở đây? Ngoài ra, những gì có thể được thực hiện để khắc phục vấn đề này?

+0

Bạn có bao gồm tiêu đề cho Rect2f không? Hay bạn đã làm một tuyên bố về phía trước? –

+0

Có, tôi đã bao gồm tiêu đề cho Rect2f. – zeboidlund

Trả lời

6

Trước hết, chúng ta hãy cố gắng làm cho mã của bạn đơn giản hơn một chút:

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

Được rồi, vì vậy bây giờ chúng ta thấy rằng ngoặc rõ ràng là cân bằng. Còn gì nữa? Hãy kiểm tra số following code snippet's error:

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

Điều này có vẻ như sử dụng kỳ lạ, nhưng thực sự tôi rất ghét rò rỉ bộ nhớ. Tuy nhiên, đầu ra có vẻ hữu ích:

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

Aha! Bây giờ chúng tôi chỉ còn lại với lỗi về các dấu ngoặc đơn. Tôi không thể tìm thấy nguyên nhân gây ra điều đó; tuy nhiên, tôi nghĩ bạn quên bao gồm tệp định nghĩa Rect2f.

+0

Ok, vậy hình dạng không được tìm thấy sau đó? – zeboidlund

+0

Không, không tìm thấy 'Rect2f'. Bạn cần phải "#include" Rect.h "' –

+0

Ở đây, tôi sẽ đăng chức năng (bao gồm cả tiêu đề), nó đến từ đâu. Một điều cần lưu ý là tôi đã có '#include" Rect.h "' – zeboidlund

0

Từ các cuộc thảo luận từ câu trả lời đầu tiên: 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".

Dường như bạn đang thiếu chức năng này từ Rect2f lớp học của bạn:

virtual bool Intersects(const Circle& c) const;

+0

Vẫn không có gì ... Tôi thực hiện với ý nghĩ rằng nó sẽ hoạt động và MinGW chỉ là ngu ngốc, nhưng tiếc là các lỗi vẫn còn. – zeboidlund

134

Đối với những người tương lai phải vật lộn với một vấn đề tương tự, tình hình là trình biên dịch chỉ đơn giản là không thể tìm thấy loại bạn đang sử dụng (ngay cả khi Intelisense của bạn có thể tìm thấy nó).

Điều này có thể được gây ra bằng nhiều cách:

  • Bạn quên #include header định nghĩa nó.
  • Nhân viên bảo vệ của bạn (#ifndef BLAH_H) bị lỗi (#ifndef BLAH_H của bạn không khớp với #define BALH_H do lỗi đánh máy hoặc sao chép + dán).
  • Hoặc, trình biên dịch đang suy nghĩ bạn có nghĩa là một phạm vi khi thực sự bạn có nghĩa khác (Ví dụ, nếu bạn có NamespaceA::NamespaceB VÀ một <global scope>::NamespaceB, nếu bạn đã trong NamespaceA, nó sẽ tìm trong NamespaceA::NamespaceB và không bận tâm kiểm tra <global scope>::NamespaceB) trừ khi bạn truy cập một cách rõ ràng.

Để truy cập một cách rõ ràng một cái gì đó trong không gian tên toàn cầu, tiền tố nó với ::, như thể không gian tên toàn cầu là một không gian tên không có tên (ví dụ ::MyType hoặc ::MyNamespace::MyType).

+5

Bạn cũng có thể sao chép và dán bảo vệ bao gồm của mình vào một tệp tiêu đề khác mà không thay đổi nó. – opyh

+1

Hai 'ngoại lệ.h' trong các thư mục con riêng biệt; cả '#ifndef __ProjectName__exceptions_'; một bao gồm khác. D'oh! – OJFord

+0

Đây là lý do tại sao tôi cài đặt clang cho studio trực quan, vì vậy tôi có thể nhận được thông báo lỗi tốt hơn khi tôi bị bối rối. – Dan

Các vấn đề liên quan