Ik probeer te begrijpen waarom het bovenstaande niet kan worden gecompileerd. Om welke reden dan ook, wanneer ik een instantie van Rect2f probeer te maken (die WEL overneemt van de klasse Shape
, specificeerde het sjabloonargument shared_ptr
, net als Circle
), krijg ik de volgende fouten:
error: expected type-specifier before 'Rect2f'
error: expected ')' before 'Rect2f'
Alles aan de Circle
shared_ptr
is prima in orde. Er zijn geen problemen mee; het is alleen de Rect2f
die problemen veroorzaakt.
Bovendien zijn de waarden die aan de constructor zijn doorgegeven geldig.
Dus, wat zou hier het probleem mee kunnen zijn? Ik heb hiervoor Rect.h
opgenomen. Kortheidshalve (en voor het geval ik iets in dat bestand heb gemist dat hierop van invloed kan zijn), zal ik het volgende posten:
Recht.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;
};
Bron van foutfunctie en bestandskop (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 );
}
Hoofdfunctietest (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();
}
Vraag
Afgaande op de geleverde fouten, wat mis ik hier? En wat kan er worden gedaan om dit probleem op te lossen?
Antwoord 1, autoriteit 100%
Voor toekomstige mensen die worstelen met een soortgelijk probleem, is de situatie dat de compiler het type dat u gebruikt gewoon niet kan vinden (zelfs als uw Intelisense het kan vinden).
Dit kan op veel manieren worden veroorzaakt:
- Je bent vergeten om
#include
de header te gebruiken die het definieert. - Uw inclusiebeveiligingen (
#ifndef BLAH_H
) zijn defect (uw#ifndef BLAH_H
komt niet overeen met uw#define BALH_H
vanwege een typfout of kopieer+plakfout). - Uw opnamewachters worden per ongeluk twee keer gebruikt (twee afzonderlijke bestanden die beide
#define MYHEADER_H
gebruiken, zelfs als ze zich in afzonderlijke mappen bevinden) - Je bent vergeten dat je een sjabloon gebruikt (bijv.
new Vector()
moetnew Vector<int>()
zijn) - De compiler denkt dat je de ene scope bedoelde terwijl je eigenlijk een andere bedoelde (bijvoorbeeld als je
NamespaceA::NamespaceB
, EN een<global scope>::NamespaceB
, als je al binnenNamespaceA
bent, zal het inNamespaceA::NamespaceB
kijken en niet de moeite nemen om<global scope>::NamespaceB
) tenzij je er expliciet toegang toe hebt. - Je hebt een naamclash (twee entiteiten met dezelfde naam, zoals een klasse en een enum-lid).
Om expliciet toegang te krijgen tot iets in de globale naamruimte, voeg je de prefix ::
toe, alsof de globale naamruimte een naamruimte is zonder naam (bijv. ::MyType
of ::MyNamespace::MyType
).
Antwoord 2, autoriteit 3%
Laten we allereerst proberen uw code een beetje eenvoudiger te maken:
// 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());
Ok, dus nu zien we dat de haakjes duidelijk in balans zijn. Wat kan het anders zijn? Laten we de volgende fout in het codefragmentcontroleren:
int main() {
delete new T();
}
Dit lijkt misschien raar gebruik, en dat is het ook, maar ik heb echt een hekel aan geheugenlekken. De uitvoer lijkt echter nuttig:
In function 'int main()':
Line 2: error: expected type-specifier before 'T'
Aha! Nu zitten we alleen met de fout over de haakjes. Ik kan niet vinden waardoor dat komt; ik denk echter dat je vergeet het bestand op te nemen dat Rect2f
definieert.