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)) );
Ich versuche zu verstehen, warum das oben genannte nicht kompiliert werden kann. Aus welchem Grund auch immer, wenn ich versuche, eine Instanz von Rect2f zu erstellen (die von der Klasse Shape
erbt, die das Template-Argument shared_ptr
spezifiziert, genau wie Circle
), erhalte ich die folgenden Fehler:
error: expected type-specifier before 'Rect2f'
error: expected ')' before 'Rect2f'
Alles an der Circle
shared_ptr
ist vollkommen in Ordnung. Es gibt keine Probleme damit; es ist nur der Rect2f
, der Probleme verursacht.
Außerdem sind die Werte, die dem Konstruktor übergeben werden, gültig.
Was könnte also das Problem bei diesem Beispiel sein? Ich habe dafür Rect.h
eingebunden. Der Kürze halber (und für den Fall, dass ich etwas in dieser Datei übersehen habe, das sich auf dieses Problem auswirken könnte), werde ich das Folgende posten:
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;
};
Fehlerursache Funktion und Dateikopf (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 );
}
Hauptfunktionstest (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();
}
Fragestellung
Nach den angegebenen Fehlern zu urteilen, was übersehe ich hier? Und was kann man tun, um dieses Problem zu beheben?
Für zukünftige Benutzer, die mit einem ähnlichen Problem zu kämpfen haben, besteht die Situation darin, dass der Compiler den Typ, den Sie verwenden, einfach nicht finden kann (auch wenn Ihr Intelisense ihn finden kann).
Dies kann viele Ursachen haben:
#include
).#ifndef BLAH_H
) sind fehlerhaft (Ihr #ifndef BLAH_H
passt nicht zu Ihrem #define BALH_H
aufgrund eines Tippfehlers oder eines Copy+Paste-Fehlers).new Vector()
sollte new Vector<int>()
sein)NamespaceA::NamespaceB
haben UND einen <globalen Bereich>::NamespaceB
, wenn Sie sich bereits in NamespaceA
befinden, wird er in NamespaceA::NamespaceB
nachsehen und sich nicht die Mühe machen, <globalen Bereich>::NamespaceB
zu überprüfen), es sei denn, Sie greifen explizit darauf zu.Um explizit auf etwas im globalen Namespace zuzugreifen, stellen Sie ihm ::
voran, als ob der globale Namespace ein Namespace ohne Namen wäre (z.B. ::MyType
oder ::MyNamespace::MyType
).
Lassen Sie uns zunächst versuchen, Ihren Code ein wenig zu vereinfachen:
// 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());
Okay, jetzt sehen wir, dass die Klammern eindeutig ausgeglichen sind. Was könnte es sonst sein? Überprüfen wir den folgenden Codeschnipsel's Fehler:
int main() {
delete new T();
}
Das mag nach einer seltsamen Verwendung aussehen, und das ist es auch, aber ich hasse Speicherlecks. Die Ausgabe scheint jedoch nützlich zu sein:
In function 'int main()':
Line 2: error: expected type-specifier before 'T'
Aha! Jetzt bleibt uns nur noch der Fehler mit den Klammern. Ich kann nicht herausfinden, woran das liegt, aber ich glaube, Sie haben vergessen, die Datei einzubinden, die Rect2f
definiert.