【问题标题】:Error: expected type-specifier before 'ClassName'错误:“ClassName”之前的预期类型说明符
【发布时间】:2012-02-09 08:01:45
【问题描述】:
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。为简洁起见(如果我错过了该文件中可能会影响这一点的内容),我将发布以下内容:

矩形.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();
}

问题

从提供的错误来看,我在这里遗漏了什么?另外,有什么办法可以解决这个问题?

【问题讨论】:

  • 您是否包含了 Rect2f 的标题?还是你做了前向声明?
  • 是的,我确实包含了 Rect2f 的标题。

标签: c++ shared-ptr pure-virtual


【解决方案1】:

对于未来遇到类似问题的人来说,情况是编译器根本找不到您正在使用的类型(即使您的 Intelisense 可以找到它)。

这可能是由多种原因引起的:

  • 您忘记#include 定义它的标头。
  • 您的包含保护 (#ifndef BLAH_H) 有缺陷(由于拼写错误或复制+粘贴错误,您的 #ifndef BLAH_H 与您的 #define BALH_H 不匹配)。
  • 您的包含保护被意外使用了两次(两个单独的文件都使用 #define MYHEADER_H,即使它们位于不同的目录中)
  • 您忘记了您正在使用模板(例如,new Vector() 应该是 new Vector&lt;int&gt;()
  • 编译器认为你的意思是一个作用域,而实际上你的意思是另一个作用域(例如,如果你有一个NamespaceA::NamespaceB 和一个&lt;global scope&gt;::NamespaceB,如果你已经在NamespaceA 中,它会在NamespaceA::NamespaceB 中查找除非您明确访问它,否则不要费心检查 &lt;global scope&gt;::NamespaceB)。
  • 您存在名称冲突(两个具有相同名称的实体,例如一个类和一个枚举成员)。

要显式访问全局命名空间中的某些内容,请在其前面加上 :: 前缀,就好像全局命名空间是一个没有名称的命名空间(例如 ::MyType::MyNamespace::MyType)。

【讨论】:

  • 两个exceptions.h在不同的子目录中;都#ifndef __ProjectName__exceptions_;一个包括另一个。哦!
  • 这就是我为 Visual Studio 安装 clang 的原因,这样当我被难住时可以得到更好的错误信息。
  • 我在两个文件中使用了相同的保护。谢谢,它有帮助。
  • 如果 2 个库包含相同的类,可能会发生非常相似的情况。最近在开发一个Argument 类时,我意外地出现了错误,结果发现是2 个using namespace(一个具有未记录的同名类)导致了该错误。
【解决方案2】:

首先,让我们试着让你的代码更简单一点:

// 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());

好的,现在我们看到括号显然是平衡的。还能是什么?让我们检查一下following code snippet's error

int main() {
    delete new T();
}

这可能看起来很奇怪,但我真的很讨厌内存泄漏。但是,输出看起来确实很有用:

In function 'int main()':
Line 2: error: expected type-specifier before 'T'

啊哈!现在我们只剩下关于括号的错误了。我找不到是什么原因造成的;但是,我认为您忘记包含定义 Rect2f 的文件。

【讨论】:

  • 好的,那么 Shape 没有找到?
  • 不,找不到Rect2f。你需要#include "Rect.h"
  • 在这里,我将发布该函数的来源(包括标题)。需要注意的一件事是我已经拥有#include "Rect.h"
  • 从错误来看,我很确定 Rect2f 出于某种原因没有被定义。尝试将 #pragma once 更改为显式包含防护。 Rect2f r;main 的函数范围内给出什么错误? Rect.h 中的 #warning 会被打印出来吗?
  • 好的,通过包含守卫,我假设典型的#ifndef #define #endif 语句。试过了,没什么变化。而且,就main() 错误而言,这就是我得到的:error: expected ';' before 'rec'。确实很奇怪……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多