c++ - Error: especificador de tipo esperado antes de ''ClassName''
shared-ptr pure-virtual (3)
Antes que nada, intentemos hacer su código un poco más simple:
// 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());
De acuerdo, entonces ahora vemos que los paréntesis están claramente equilibrados. ¿Qué más podría ser? Comprobemos el siguiente error del fragmento de código :
int main() {
delete new T();
}
Esto puede parecer un uso extraño, y lo es, pero realmente odio las pérdidas de memoria. Sin embargo, el resultado parece útil:
In function ''int main()'':
Line 2: error: expected type-specifier before ''T''
Aha! Ahora nos queda el error sobre los paréntesis. No puedo encontrar lo que causa eso; sin embargo, creo que te estás olvidando de incluir el archivo que define Rect2f
.
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)) );
Estoy tratando de entender por qué lo anterior no se compilará. Por cualquier motivo, cuando intento crear una instancia de Rect2f (que hereda de la clase Shape
especifica el argumento de la plantilla shared_ptr
, como Circle
), obtengo los siguientes errores :
error: expected type-specifier before ''Rect2f''
error: expected '')'' before ''Rect2f''
Todo sobre el Circle
shared_ptr
está perfectamente bien. No hay problemas con eso; es solo el Rect2f
que está causando problemas.
Además, los valores pasados al constructor son válidos.
Entonces, ¿cuál podría ser el problema con este? Tengo Rect.h
incluido para esto. En aras de la brevedad (y en caso de que haya olvidado algo en ese archivo que pueda estar afectando esto), publicaré lo siguiente:
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;
};
Fuente de la función de error y encabezado del archivo (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 );
}
Prueba de función principal (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();
}
Pregunta
A juzgar por los errores proporcionados, ¿qué me falta aquí? Además, ¿qué se puede hacer para rectificar este problema?
De la discusión de la primera respuesta: http://chat..com/rooms/6681/discussion-between-holland-and-anton-golov
Anton: Me da el error "no se puede asignar un objeto de tipo abstracto ''Rect2f'' porque las siguientes funciones virtuales son puras dentro de ''Rect2f'': bool virtual Shape :: Intersects (const> Circle &) const".
Parece que te está faltando esta función de tu clase Rect2f
:
virtual bool Intersects( const Circle& c ) const;
Para las personas del futuro que luchan con un problema similar, la situación es que el compilador simplemente no puede encontrar el tipo que está utilizando (incluso si su Intelisense puede encontrarlo).
Esto puede ser causado de muchas maneras:
- Olvidó
#include
el encabezado que lo define. - Sus guardias de inclusión (
#ifndef BLAH_H
) son defectuosas (su#ifndef BLAH_H
no coincide con su#define BALH_H
debido a un error tipográfico o de copiar y pegar). - O bien, el compilador cree que usted quiso decir un alcance cuando realmente quería decir otro (por ejemplo, si tiene
NamespaceA::NamespaceB
, AND a<global scope>::NamespaceB
, si ya está dentro deNamespaceA
, se verá enNamespaceA::NamespaceB
y no molestarse en verificar<global scope>::NamespaceB
) a menos que accedas explícitamente.
Para acceder explícitamente a algo en el espacio de nombre global, prefímalo con ::
, como si el espacio de nombres global fuera un espacio de nombres sin nombre (por ejemplo, ::MyType
o ::MyNamespace::MyType
).