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)) );
J'essaie de comprendre pourquoi ce qui précède ne compile pas. Quelle que soit la raison, lorsque j'essaie de créer une instance de Rect2f (qui hérite de la classe Shape
spécifiée avec l'argument de modèle shared_ptr
, Exactement comme Circle
), après erreurs:
error: expected type-specifier before 'Rect2f'
error: expected ')' before 'Rect2f'
Tout ce qui concerne Circle
shared_ptr
Est parfaitement correct. Il n'y a pas de problèmes avec cela; c'est seulement le Rect2f
qui pose problème.
De plus, les valeurs transmises au constructeur sont valides.
Alors, quel pourrait être le problème avec celui-ci? J'ai Rect.h
Inclus pour cela. Par souci de brièveté (et au cas où j'aurais oublié quelque chose dans ce fichier qui pourrait l'affecter), je posterai ce qui suit:
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;
};
source de la fonction d'erreur et en-tête de fichier (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 de fonction principale (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();
}
Question
À en juger par les erreurs fournies, qu'est-ce qui me manque ici? Aussi, que peut-on faire pour remédier à ce problème?
Pour les futurs utilisateurs aux prises avec un problème similaire, le compilateur ne peut tout simplement pas trouver le type que vous utilisez (même si votre Intelisense peut le trouver).
Cela peut être causé de plusieurs façons:
#include
l'en-tête qui le définit.#ifndef BLAH_H
) sont défectueux (votre #ifndef BLAH_H
ne correspond pas à votre #define BALH_H
en raison d'une faute de frappe ou d'une erreur copier-coller).NamespaceA::NamespaceB
, ET un <global scope>::NamespaceB
, si vous êtes déjà dans NamespaceA
, il regardera dans NamespaceA::NamespaceB
et pas la peine de vérifier <global scope>::NamespaceB
) sauf si vous y accédez explicitement.Pour accéder explicitement à quelque chose dans l'espace de noms global, préfixez-le avec ::
, comme si l’espace de noms global était un espace de noms sans nom (par exemple, ::MyType
ou ::MyNamespace::MyType
).
Tout d’abord, essayons de simplifier un peu votre code:
// 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());
Bon, voyons maintenant que les parenthèses sont clairement équilibrées. Quoi d'autre cela pourrait-il être? Vérifions le erreur de l'extrait de code suivant :
int main() {
delete new T();
}
Cela peut sembler étrange, et c’est vrai, mais je déteste vraiment les fuites de mémoire. Cependant, le résultat semble utile:
In function 'int main()':
Line 2: error: expected type-specifier before 'T'
Aha! Il ne nous reste plus maintenant que l'erreur concernant les parenthèses. Je ne trouve pas ce qui cause ça. Cependant, je pense que vous oubliez d'inclure le fichier qui définit Rect2f
.
De la discussion de la première réponse: http://chat.stackoverflow.com/rooms/6681/discussion-between-holland-and-anton-golov
Anton: Cela me donne l’erreur "ne peut pas allouer un objet de type abstrait‘ Rect2f ’car les> fonctions virtuelles suivantes sont pures dans‘ Rect2f ’: bool virtuel Shape :: Intersects (const> Circle &) const".
Il semble que cette fonction manque dans votre classe Rect2f
:
virtual bool Intersects( const Circle& c ) const;