Error expected class name before token

  • Forum
  • General C++ Programming
  • Expected class-name before { token

Expected class-name before { token

I’ve encountered another problem whilst trying to compile a fairly large codebase(about 20 classes). I’m getting the following compiler-error:


/path/to/Sphere.h|9|error: expected class-name before ‘{’ token

This is the problematic code:

1
2
3
#include "GeometricObject.h"

class Sphere : public GeometricObject {

Since there are quite a lot of files, I’m not expecting there to be a straight forward solution to this, but how would I go about finding a solution to this? If someone could point me in the right direction, I would be very grateful;)

It looks like the compiler does not know what GeometricObject is. Find the definition (grep) and verify that it (and its header) is spelled correctly, available in Sphere’s namespace, and public.

I think all that should be covered, but if you would care to take a look, here’s the GeometricObject class

GeometricObject.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

#ifndef __GEOMETRICOBJECT__
#define __GEOMETRICOBJECT__

class RGBColor;
class ShadeRec;

#include "Ray.h"
#include "ShadeRec.h"
#include "RGBColor.h"

class GeometricObject {
	public:
		GeometricObject(void);
        	GeometricObject(const GeometricObject& g);
		virtual ~GeometricObject(void);

		virtual bool hit(const Ray& ray, double& tmin, ShadeRec& sr) const = 0;
	protected:
		RGBColor color;	//to be replaced

        GeometricObject& operator =(const GeometricObject& rhs);
};

#endif 

GeometricObject.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#include "GeometricObject.h"

GeometricObject::GeometricObject(void) : color(0.0, 0.0, 0.0) {
}

GeometricObject::GeometricObject(const GeometricObject& g) {
}

GeometricObject::~GeometricObject(void) {
}

GeometricObject& GeometricObject::operator =(const GeometricObject& rhs) {
        if (this == &rhs) {
            return (*this);
        }
        color = rhs.color;
        return (*this);
}

1
2
3
4
5
6
#ifndef __GEOMETRICOBJECT__
#define __GEOMETRICOBJECT__

...

#endif 

You might want to check to make sure you have not defined __GEOMETRICOBJECT__ in another file by accident (copy/paste?) since doing so would skip your definition of GeometricObject. The compiler doesn’t seem to think GeometricObject is a class name. Your declaration of Sphere looks correct, so I would guess that the problem is with the base class.

Ok, I checked that now, and it seems fine, I cant see any definitions of __GEOMETRICOBJECT__ anywhere else. I realize now that I forgot to include the full compiler error, maybe that could help:


In file included from World.h:11:0,
                 from ShadeRec.h:9,
                 from GeometricObject.h:9,
                 from GeometricObject.cpp:2:
Sphere.h:9:39: error: expected class-name before ‘{’ token

Ok, here is what happens:
* GeometricObject.cpp includes GeometricObject.h in order to get the definition for class GeometricObject
* GeometricObject.h includes ShadeRec.h in order to get the definition of ShadeRec. Notice that at this point GeometricObject is not defined yet.
* some other include stuff along the chain
* Sphere.h tries to include GeometricObject.h, but the guarding token

__GEOMETRICOBJECT__

has been already defined and nothing happens
* class Sphere tries to derive from Geometric object, but it still has no definition. It will later, after the preprocessor returns from the ShadeRec.h include inside GeometricObject.h, but this is no use at this point

What can you do?
You can use forward declaration as you have used already in some places. Such declaration tells the compiler that you know a certain class is defined somewhere, but you disclose nothing yet about its interface and members.

You can not do this:

1
2
3
4
5
6
// remove #include "GeometricObject.h"

class GeometricObject; // the fore-mentioned forward declaration

class Sphere : public GeometricObject {
...

, because this is inheritance, and the forward declaration provides no information on the size of the GeometricObject class, nor on the interface.

But you can do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef __GEOMETRICOBJECT__
#define __GEOMETRICOBJECT__

class RGBColor;
class ShadeRec; // you already have forward declaration

#include "Ray.h"
// optionally remove #include "ShadeRec.h"
#include "RGBColor.h"

class GeometricObject {
	public:
		GeometricObject(void);
        	GeometricObject(const GeometricObject& g);
		virtual ~GeometricObject(void);

		virtual bool hit(const Ray& ray, double& tmin, ShadeRec& sr) const = 0;
	protected:
		RGBColor color;	//to be replaced

        GeometricObject& operator =(const GeometricObject& rhs);
};

#endif 

, because GeometricObject only refers to ShadeRec, it does not contain ShadeRec objects as member variables and doesn’t inherit from the ShadeRec class.

It is impossible to have mutual containment, like A contains/derives from B, and B contains/derives from A. This would create infinite recursion between the definitions of those two classes.

Regards

You, my good Sir, are a genius! That solves the issue! Thanks so much for taking the time:)

Actually, I made a mistake :) I wrote that you should optionally remove

#include «ShadeRec.h»

. You should definitely remove it. Nonetheless, I’m glad you worked it out.

Regards

Topic archived. No new replies allowed.

Viktor10

0 / 0 / 0

Регистрация: 01.11.2015

Сообщений: 62

1

30.11.2016, 09:17. Показов 11872. Ответов 3

Метки нет (Все метки)


Помогите пожалуйста, при запуске программы выходят такие ошибки
Ошибки:

3 C:prog8_vers2Car.cpp In file included from Car.cpp
5 C:prog8_vers2Car.h expected class-name before ‘{‘ token
C:prog8_vers2Makefile.win [Build Error] [Car.o] Error 1

main

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <cstdlib>
#include <iostream>
#include "Object.h"
#include "Car.h"
//#include "Lorry.h"
//#include "Vector.h"
using namespace std;
 
int main(int argc, char *argv[])
{
    Car *a=new Car;//создаем объект класса Car
    a->Input();
//  Lorry *b=new Lorry; //создаем объект класса Lorry
//  b->Input();
    /*Vector v(10);//Создаем вектор
    Object*p=a;//ставим указатель на объект класса Car
    v.Add(p);//добавляем объект в вектор
    p=b;//ставим указатель на объект класса Lorry
    v.Add(p); //добавляем объект в вектор
    v.Show();//вывод вектора
    v.Del();//удаление элемента
    cout<< "nVector size="<<v();
    */
    system("PAUSE");
    return EXIT_SUCCESS;
}
C++
1
2
3
4
5
6
7
8
9
using namespace std;
class Object
{
public:
Object(void);
virtual void Show()=0;
virtual void Input()=0;
virtual ~Object(void);
};
C++
1
2
3
4
5
6
7
#include "Object.h"
Object::Object(void)
{
}
Object::~Object(void)
{
};

Car.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <string>
using namespace std;
class Car:
 public Object
{
 public:
        Car(void);//конструктор без параметров
 public:
        virtual ~Car(void);//деструктор
        void Show();//функция для просмотра атрибутов класса с помощью указателя
        void Input();//функция для ввода значений атрибутов
        Car(string,int,int);//конструктор с параметрами
        Car(const Car&);//конструктор копирования
        //селекторы
        string Get_mark(){return mark;}
        int Get_cyl(){return cyl;}
        int Get_power(){return power;}
        //модификаторы
        void Set_mark(string);
        void Set_cyl(int);
        void Set_power(int);
        Car&operator=(const Car&);//перегрузка операции присваивания
        protected:
                  string mark;
                  int cyl;
                  int power;
 };

car.cpp

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <string>
#include "Car.h"
using namespace std;
//конструктор без параметров
Car::Car(void)
{
    mark="";
    cyl=0;
    power=0;
}
//деструктор
Car::~Car(void)
{
}
//констрктор с параметрами
Car::Car(string M,int C,int P)
{
    mark=M;
    cyl=C;
    power=P;
}
//конструктор копирования
Car::Car(const Car& car)
{
    mark=car.mark;
    cyl=car.cyl;
    power=car.power;
}
//селекторы
void Car::Set_cyl(int C)
{
    cyl=C;
}
void Car::Set_mark(string M)
{
    mark=M;
}
void Car::Set_power(int P)
{
    power=P;
}
//оператор присваивания
Car&Car::operator=(const Car&c)
{
    if(&c==this)return *this;
        mark=c.mark;
        power=c.power;
        cyl=c.cyl;
    return *this;
}
//метод для просмотра атрибутов
void Car::Show()
{
    cout<<"nMARK : "<<mark;
    cout<<"nCYL : "<<cyl;
    cout<<"nPOWER : "<<power;
    cout<<"n";
}
//метод для ввода значений атрибутов
void Car::Input()
{
    cout<<"nMark:"; cin>>mark;
    cout<<"nPower:";cin>>power;
    cout<<"nCyl:";cin>>cyl;
};

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Эксперт С++

1623 / 953 / 782

Регистрация: 06.02.2016

Сообщений: 2,449

Записей в блоге: 30

30.11.2016, 11:17

2

Файл Car.h ничего не знает о существовании такого класса как Object



0



0 / 0 / 0

Регистрация: 01.11.2015

Сообщений: 62

30.11.2016, 11:31

 [ТС]

3

Цитата
Сообщение от Peoples
Посмотреть сообщение

Файл Car.h ничего не знает о существовании такого класса как Object

добавлял #include «Object.h» в файл car.cpp
та же самая ошибка



0



7275 / 6220 / 2833

Регистрация: 14.04.2014

Сообщений: 26,871

30.11.2016, 11:48

4

В car.h добавляй.



0



Содержание

  1. Error expected before token class name
  2. Error expected before token class name
  3. Error expected before token class name

Error expected before token class name

I’ve encountered another problem whilst trying to compile a fairly large codebase(about 20 classes). I’m getting the following compiler-error:

This is the problematic code:

Since there are quite a lot of files, I’m not expecting there to be a straight forward solution to this, but how would I go about finding a solution to this? If someone could point me in the right direction, I would be very grateful;)

I think all that should be covered, but if you would care to take a look, here’s the GeometricObject class

You might want to check to make sure you have not defined __GEOMETRICOBJECT__ in another file by accident (copy/paste?) since doing so would skip your definition of GeometricObject. The compiler doesn’t seem to think GeometricObject is a class name. Your declaration of Sphere looks correct, so I would guess that the problem is with the base class.

Ok, I checked that now, and it seems fine, I cant see any definitions of __GEOMETRICOBJECT__ anywhere else. I realize now that I forgot to include the full compiler error, maybe that could help:

Ok, here is what happens:
* GeometricObject.cpp includes GeometricObject.h in order to get the definition for class GeometricObject
* GeometricObject.h includes ShadeRec.h in order to get the definition of ShadeRec. Notice that at this point GeometricObject is not defined yet.
* some other include stuff along the chain
* Sphere.h tries to include GeometricObject.h, but the guarding token __GEOMETRICOBJECT__ has been already defined and nothing happens
* class Sphere tries to derive from Geometric object, but it still has no definition. It will later, after the preprocessor returns from the ShadeRec.h include inside GeometricObject.h, but this is no use at this point

What can you do?
You can use forward declaration as you have used already in some places. Such declaration tells the compiler that you know a certain class is defined somewhere, but you disclose nothing yet about its interface and members.

You can not do this:

, because this is inheritance, and the forward declaration provides no information on the size of the GeometricObject class, nor on the interface.

But you can do this:

, because GeometricObject only refers to ShadeRec, it does not contain ShadeRec objects as member variables and doesn’t inherit from the ShadeRec class.

It is impossible to have mutual containment, like A contains/derives from B, and B contains/derives from A. This would create infinite recursion between the definitions of those two classes.

Источник

Error expected before token class name

I was once again working on a Framework using inheritance when I encountered the following error:

C:..C++ & SDL2SDL Game DevelopmentPlayer.h|10|error: expected class-name before ‘<‘ token

I’ve researched a bit on the inet. The error was often in combination with a missing #include. So I went on and put all of my header-files within the Player class but I ended up with the same error. Here are the files that I think are related to the Problem:

Hope someone’s able to help me out here 🙂

Thanks for your correction. I’ve deleted the semicolon but funnily I’m still getting the error at the exact same point :/

Any idea where else I’m wrong? Should I upload the .cpp files as well?

Yep. The I’m retyping this from SDL Game Development by Shaun Mitchell.

I think you’re missing a forward declaration, this part is a total shot in the dark but I think it might be for the ‘SDL_Renderer’ object. Add this to your top most header file:

That book catches a lot of flak on Amazon for having annoying little errors in the code. Most people say that it isn’t for beginners.

Thanks for your work. I’m well aware that the book is being criticized and quite error prone. I’ve already had to fix quite a few to get this Point. The book leaves out some parts and it’s definitly unusable for a total beginner. However, my experience with coding is quite limited as well.

The SDL_Renderer is as far as my knocklegde of SDL goes, included in the normal Header (SDL.h) and a normal class like SDL_Window for e.g.

In Player.h, SDLGameObject and GameObject, you only need a forward declaration to LoaderParams. So you can use the following:

You have a circular dependency.

Game.h includes Player.h
Player.h includes SDLGameObject.h
SDLGameObject.h includes Game.h

To avoid this problem I recommend only using include for your own headers if you need to. If you only have pointers and references to a class a forward declaration is enough. doug4 has shown you how to do this.

You will probably have to add the includes in the source files (.cpp) instead, because the full class definition is needed when you create objects, call functions and in other ways use the members of the class.

Источник

Error expected before token class name

I have made a class called LockableBitSet, that extends bitset in the standard library. But when I try to compile my project, I get the «expected class-name before ‘<‘ token» error in the header file. Here is the code:

Now, I’ve done enough googling to know that this seems to be a matter of the compiler not knowing the type bitset when it gets to the class definition. But that’s what I don’t understand, since I include the bitset header first, so I would expect it to have read that entire file and thus the bitset class definition by that time.

Nevertheless, I tried out forward declaration like so:

Which just gives me the error «invalid use of template-name ‘std::bitset’ without an argument list. I have also read about a possible cause being circular references, but since I’m extending bitset, I can’t see how that would be the case.

And while I doubt it’s really a problem with the class itself, here it is, just for good measure:

So what am I doing wrong in the header file? While I’m new to C++, I have done a fair bit of tutorial reading and error searching, and I fail to see what the problem is in this case, or rather how to solve it.

Oh, and FYI I am using C++11, which is why I declare the locked variable like that.

std::bitset<> is not designed for inheritance; consider something like this instead:

> Does that mean that I can’t make a class that extends it, or merely that I shouldn’t?

No, you can extend it.
Just that you should not publicly inherit from a std::bitset<> to extend it.

> and that I need to be able to lock it down from being edited, thus the LockableBitSet class.

The problem with public inheritance is this:

If you are not already doing it, you should also provide a RAII wrapper a la std::lock_guard
http://en.cppreference.com/w/cpp/thread/lock_guard

Yes, this problem is exactly what I was planning to solve with this lock class, by also overriding some of the operators and setters in the bitset. But my reason for wanting a lock is not due to anything thread-related but to avoid the very problem you point out with bitsets, for one of my own classes. I.e. making sure that once it’s locked, none of the data inside the class can be changed, which in this case means keeping the bitset as it is when lock() is called.

I can figure out that this is not best practice, but like I said I’m new to C++, so why is it a bad idea to publicly inherit bitset to extend it? After all, that IS what polymorphism is for, and I see no difference between extending my own class and a standard library class. So please enlighten me.

> making sure that once it’s locked, none of the data inside the class can be changed,
> which in this case means keeping the bitset as it is when lock() is called.

If you inherit publicly from a std::bitset<> , there is an implicit conversion from lockable_bitset & to std::bitset & . Which defeats the very purpose of a lockable_bitset<> ; std::bitset<> knows nothing about any lock.
See: http://www.objectmentor.com/resources/articles/lsp.pdf

Since a std::bitset is inexpensive to copy, it may be simpler to just make a copy of the bitset when it is ‘locked’, use the copy, and restore the bitset from the copy when it is ‘unlocked’.

I see what you mean, but that is exactly what I have planned to solve by overriding those operators that change the bitset, like sets and &= and so on, and in those I will simply just call my isUnlocked() function, and only if it returns true, will I call the same function from bitset. That way I ensure that whatever class extends LockableBitset can’t be modified if it’s been locked.

I will read through the linked article and think about what you have said as well. But returning to the original question, is there a fix for that error that lets me still have LockableBitset as a class, not a struct, AND extend bitset? I’m not saying I will end up using it, but I would never the less like to know how to fix that error.

> that is exactly what I have planned to solve by overriding those operators
> that change the bitset, like sets and &= and so on

You can’t override functions that are not virtual .
Even if you hide the name of a non-virtual function in a derived class (bad idea), the derived class function won’t prevail when applied on an object accessed via a reference to the base class.
http://ideone.com/CfejwQ

> is there a fix for that error

Aha, well this changes things a bit. I had assumed that bitset was a class. I’ve been reading up on templates, and concluded that I CAN extend a bitset with a class (not a struct), which was what I wanted to know. And I understand your third example, where I would then add methods to my class that would then change the private field impl. And I understand that the keyword using in the second example means you’re doing name hiding, thus making sure that the method called will be in the child class of any method I choose to define there that are also in the bitset class.

But since you say that bitset is not made for inheritance, why do you still extend it in the second example? I see that it becomes private, but what difference does that make when it’s still an extension?

And then there’s the matter of the part in the sharp brackets. From what I’ve read about templates, they are for specifying functions that can handle all kinds of different data types. But for bitset, it’s just a size_t integer. So how come it’s not just a class that has NBITS as a parameter instead?

And in my case my LockedBitSet will be always of size 50. When using your code with my class, I then get the error ‘template used without template parameters’ for my cpp file. Is there a way I can specify the size to be 50 in the header file, so I don’t have to add the brackets to every method in the cpp file?

> I see that it becomes private, but what difference does that make when it’s still an extension?

> But for bitset, it’s just a size_t integer.
> So how come it’s not just a class that has NBITS as a parameter instead?

Primarily for performance reasons, when NBITS is a constant known at compile time.

For a bitset, where the number of bits can be specified at run time, see boost::dynamic_bitset<>
http://www.boost.org/doc/libs/1_54_0/libs/dynamic_bitset/dynamic_bitset.html

> And in my case my LockedBitSet will be always of size 50. When using your code with my class,
> I then get the error ‘template used without template parameters’ for my cpp file.
> Is there a way I can specify the size to be 50 in the header file,
> so I don’t have to add the brackets to every method in the cpp file?

Define members of a template class in the header file.

For cpp files, where the class is used, we can provide a type alias.

And then, in your cpp file:
lockable_bitset my_bitset ;

If you want to commit your design to: we will never, ever, have to use a lockable_bitset with anything other than 50 bits, then don’t make it a template at all:

Alright, but you’re using your design suggestions as the basis for your solutions. I’m still extending the template with my class in my code. I’m not saying that will be the final design, you have brought up a lot of good points as to why it shouldn’t, but that is what I’m debugging right now, and I need to learn how to fix those errors first, before I move on to choosing a different design. So using this code as my header file

how do I add the 50, so I can use this code for my cpp file.

That is all I want to know, as long as I don’t get more errors when I’ve fixed this one.

Oh, and I did try using in my header file, but that still gives me the same error in my cpp file.

Edit: Well, I checked your link, but it doesn’t explain why private inheritance is better than public, that’s in part 2 though, which can be read here.

I can’t say that I agree with the reasoning, in the Square is a Rectangle example, if you have a field of type Rectangle, then you only need to know it’s a rectangle, and if you have one of type Square, you only need to know that it’s a Square, that a Rectangle field that contains a Square object which gets both its height and width set at the same time, well I don’t see how that can possibly be important, since you only need to know that it does everything a Rectangle would do.

BUT I recognize that in C++, public inheritance is to be avoided at pretty much all costs, so I will take it to heart. I just don’t understand it, nor agree with it. But I will follow it.

> BUT I recognize that in C++, public inheritance is to be avoided at pretty much all costs,
> so I will take it to heart.

Public inheritance is to be avoided at pretty much all costs if
a. the base class is not designed for inheritance
b. there would be a violation of the Liskov Substitution Principle

> So using this code as my header file .
> how do I add the 50, so I can use this code for my cpp file. .

Make LockableBitSet a non-template:

Well well, that got rid of all errors. So now I can focus on redesigning my project. It’s something that I’ve originally made in Java, where inheriting makes the most sense to me, but since I need to use it for BOINC, I have to adapt it to C++, which has a lot of different design principles, like that principle you mention, which I have never heard of before.

Either way, I owe you a big thank you for helping me out so much, and now I’ve got a lot of reading material, so I can learn how to best code in C++, so it’s been a good exercise to try and get this to compile. Thank you once again.

Источник

Ошибка этого вида обычно возникает при попытке использовать тип данных, который еще не определен.

Пример. Есть основной класс mother и подкласс daughter:

//main.cpp
#include "mother.h"
#include "daughter.h"
#include <iostream>

using namespace std;

int main()
{
    cout << "Hello world!" << endl;
    mother mom;
    mom.saywhat();
    return 0;
}
//mother.h
#ifndef MOTHER_H
#define MOTHER_H

class mother
{
public:
    mother();
    void saywhat();
};

#endif // MOTHER_H
//mother.cpp
#include "mother.h"
#include <iostream>

using namespace std;

mother::mother()
{
}

void mother::saywhat()
{
    cout << "WHAAAAAAT" << endl;
}
//daughter.h
#ifndef DAUGHTER_H
#define DAUGHTER_H

class daughter: public mother
{
public:
    daughter();
};

#endif // DAUGHTER_H
//daughter.cpp
#include "daughter.h"
#include "mother.h"
#include <iostream>

using namespace std;

daughter::daughter()
{
}

Компилятор выдает следующую ошибку:

daughter.h  5  error: expected class-name before ‘{’ token

Проблема в том, что при создании класса daughter базовый класс mother еще не определен. Исправляется это добавлением в daughter.h строки

//daughter.h
#ifndef DAUGHTER_H
#define DAUGHTER_H

#include "mother.h" // добавленная строка

class daughter: public mother
{
public:
    daughter();
};

#endif // DAUGHTER_H

I am getting the following error when attempting to compile my sketch:

In file included from sketch.ino:24:0: SerialRenderer.h:7: error:
expected class-name before ‘{‘ token

SerialRenderer.h

#ifndef SERIALRENDERER_H_
#define SERIALRENDERER_H_

#include <MenuSystem.h>

class SerialRenderer : public MenuComponentRenderer
{
public:
    SerialRenderer();
    virtual ~SerialRenderer();

public: // methods from MenuComponentRenderer
    virtual void render(Menu const& menu) const;
    virtual void render_menu_item(MenuItem const& menu_item) const;
    virtual void render_back_menu_item(BackMenuItem const& menu_item) const;
    virtual void render_numeric_menu_item(NumericMenuItem const& menu_item) const;
    virtual void render_menu(Menu const& menu) const;
};

#endif // SERIALRENDERER_H_

The contents of MenuSystem.h can be found at https://github.com/jonblack/arduino-menusystem/blob/master/MenuSystem.h.

It seems like the include of MenuSystem.h does not happen when SerialRenderer.h is included from my main sketch file. I get the same error if the include in SerialRenderer.h is removed.

Is there something simple I am missing for the compiler to be able to «see» MenuSystem.h?

EDIT:

Turns out I was looking at a newer version of the arduino-menusystem library than I had installed (version 2.1.1). That version did not have a class called MenuComponentRenderer.

I pulled the latest version from https://github.com/jonblack/arduino-menusystem/tree/master and it compiles fine.

Понравилась статья? Поделить с друзьями:
  • Error expected asm or attribute before token
  • Error expected primary expression before long
  • Error expected after class definition
  • Error expected primary expression before int
  • Error expected primary expression before float