Ошибка: ожидаемый тип-спецификатор перед 'ClassName'
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
), я получаю следующие ошибки
error: expected type-specifier before 'Rect2f'
error: expected ')' before 'Rect2f'
Все о Circle
shared_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 );
}
Главный тест функции (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();
}
Вопрос
Судя по предоставленным ошибкам, что мне здесь не хватает? Кроме того, что можно сделать, чтобы исправить эту проблему?
Ответы
Ответ 1
Для будущих людей, борющихся с аналогичной проблемой, ситуация заключается в том, что компилятор просто не может найти тип, который вы используете (даже если ваш Intelisense может его найти).
Это может быть вызвано разными способами:
- Вы забыли
#include
заголовок, который его определяет.
- У вас есть дефекты (
#ifndef BLAH_H
) (ваш #ifndef BLAH_H
не соответствует вашему #define BALH_H
из-за ошибки опечатки или копирования + пасты).
- Или, компилятор думает, что вы имели в виду одну область, когда вы действительно имели в виду другую (например, если у вас есть
NamespaceA::NamespaceB
, а a <global scope>::NamespaceB
, если вы уже в пределах NamespaceA
, он будет выглядеть в NamespaceA::NamespaceB
и не проверять <global scope>::NamespaceB
), если вы явно не обращаетесь к нему.
Чтобы явно получить доступ к чему-либо в глобальном пространстве имен, префикс его ::
, как если бы глобальное пространство имен было пространством имен без имени (например, ::MyType
или ::MyNamespace::MyType
).
Ответ 2
Прежде всего, попробуйте сделать ваш код немного проще:
// No need to create a circle unless it is clearly necessary to
// demonstrate the problem
// Your Rect2f defines a default constructor, so let use it for simplicity.
shared_ptr<Shape> rect(new Rect2f());
Хорошо, теперь мы видим, что круглые скобки четко сбалансированы. Что еще это может быть? Позвольте проверить следующую ошибку фрагмента кода:
int main() {
delete new T();
}
Это может показаться странным использованием, и это так, но я действительно ненавижу утечки памяти. Однако вывод кажется полезным:
In function 'int main()':
Line 2: error: expected type-specifier before 'T'
Ага! Теперь мы просто оставили ошибку в круглых скобках. Я не могу найти причину этого; однако, я думаю, вы забываете включить файл, который определяет Rect2f
.
Ответ 3
Из обсуждения первого ответа:
http://chat.stackoverflow.com/rooms/6681/discussion-between-holland-and-anton-golov
Антон: Это дает мне ошибку "не может выделить объект абстрактного типа" Rect2f, потому что > следующие виртуальные функции чисты внутри "Rect2f: virtual bool Shape:: Intersects (const > Circle &) const".
Похоже, вам не хватает этой функции из класса Rect2f
:
virtual bool Intersects( const Circle& c ) const;