Error : 'class' type redefinition

Hello,
I have structure of my classes as follows

Object.cpp
1
2
3
class Object
{
};


Integer.cpp
1
2
3
4
5
#include "Object.cpp"

class Integer : public Object
{
};


Boolean.cpp
1
2
3
4
5
#include "Object.cpp"

class Boolean : public Object
{
};


Main.cpp
1
2
3
4
5
6
7
8
9
#include "Integer.cpp"
#include "Object.cpp"

int main()
{
   Integer i;
   Boolean b;
   return 0;
}



When i compile the project i get error as

error C2011: 'Object' : 'class' type redefinition

Now, in Main.cpp file i make use of both Integer and Boolean so isn't including this files valid?

help appreciated
amal
Yes you will get C2011: 'Object' : 'class' type redefinition
error.

This is because main.cpp line 1 - includes interger.cpp which itself includes object.cpp.
and on line 2 there is include object.cpp
So object cpp gets included twice which means that class Object is seen twice by the compiler - hence the error.


The way you are including cpp files is not the recommended way of doing things.
Class declarations are usually put into header files. The code for the class is put into the cpp file.
The header file should have a header guard to prevent multiple inclusion errors.

Example of header guard

object.h
1
2
3
4
5
6
7
8
//header guard at start of header file
#ifndef OBJECT_H
#define OBJECT_H
class Object
{
};
//End guard at bottom of header file
#endif 


Do something similar for the other class declaration files;
integer.h
1
2
3
4
5
6
7
8
#ifndef INTEGER_H
#define INTEGER_H
#include "Object.h"

class Integer : public Object
{
};
#endif 


boolean.h
1
2
3
4
5
6
7
8
9
#ifndef BOOLEAN_H
#define BOOLEAN_H
#include "Object.h"

class Boolean : public Object
{
};

#endif 



Then in main.cpp you will have:
1
2
3
4
5
6
7
8
9
10
#include "Integer.h"
#include "Object.h" //probably won't need this line
#include boolean.h

int main()
{
   Integer i;
   Boolean b;
   return 0;
}

Thanks, guestgulkan ...that helped...
Hello,
I am facing a tye cast problem, but logically it seems right.

Modifying Integer.cpp

1
2
3
4
5
6
7
8
9
10
11
12


class Integer : public Object
{
     Object& getElementAt(int index);
};

Object& Integer::getElementAt(int index)
{
   return // some process to return reference to Object
}
 



Modifying Main.cpp
1
2
3
4
5
6
int main()
{
   Integer i;
   Boolean b=(Boolean)i.getElementAt(0);  // giving compile time error
   return 0;
}


The error given is :-

'type cast' : cannot convert from 'class Object' to 'class Boolean'

An Object is been returned which is just type casted to Child-class(Boolean).

What am i missing?

help appreciated
amal
Sometimes what can be casted to what sometimes confues me.

But the Object& Integer::getElementAt(int index) returns a reference.

So change this line Boolean b=(Boolean)i.getElementAt(0); to read like this:

Boolean b = static_cast<Boolean&>(i.getElementAt(0));

NOTE:
Casting a derived class to a base class is not always safe.
Yes, this cast only works in very limited cases and there are trivial ways to modify Integer and/or Boolean that would cause this code to fail eventually.

Without stepping onto the design soapbox, perhaps one solution would be to write some casting constructors:

1
2
3
4
5
6
7
class Integer : public Object {
    explicit Integer( const Boolean& b );
};

class Boolean : public Object {
    explicit Boolean( const Integer& i );
};


Hello,
I thought i understood the passing objects by reference well...not though....


Modifying Object.cpp
1
2
3
class Object
{
};


Modifying Integer.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Integer:public Object
{
	public:
			int value;
			Integer(int value);
			~Integer();
			int intValue();
};

Integer::Integer(int value)
{
	Integer::value=value;
}

Integer::~Integer()
{
	value=0;
	DBGPRINTF("Destructor of Integer ",value);
}

int Integer::intValue()
{
	return value;
}



Adding Vector.cpp

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
class Vector:public Object
{
	public:			
			Vector();
			~Vector();
			void addElement(Object& object);			
			int size();
			Object& elementAt(int index);
	private:
			int datasize;
			Object* data;
};

Vector::Vector()
{
	datasize=0;
	data=new Object[100];
}

Vector::~Vector()
{
	delete [] data;
	DBGPRINTF("Destructor of Vector");
}

void Vector::addElement(Object& object)
{
	data[datasize]=object;
	datasize++;
}

Object& Vector::elementAt(int index)
{
	return data[index];
}

int Vector::size()
{
	return datasize;
}


Modifying Mainc.pp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
     Vector v;
     Integer a(100);
     Integer b(200);
     v.addElement(a);
     v.addElement(b);

     Integer c=static_cast<Integer&>(v.elementAt(0));

    int value_a=a.intValue(); // 100
    int value_c=c.intValue();  // -842198006

    return 0;
}



Now logically, value_a and value_b should be same.

Because, i have passed Integer object by reference.

It means Integer Reference "a" and "c" should be same...but it seems they aren't.

what have i missed?

Looked at concept of passing by references on net...the concept applied seems to be same.

help appreciated
amal
Your problem is called splicing.

In Vector, you declare an array of Objects by pointer: Object* data;.
When you new Object[100], you are allocating memory for 100 Objects. Object is an empty class.

Now in addElement, you take an object passed by reference and put it into the array. The array holds only Objects, however. This means that the compiler is "splicing" your parameter into two pieces -- the Object part and "the "rest" -- and it is copying ONLY THE Object PART into the array.

You have essentially lost the derived portion of your object at this point. This, of course, then makes your static_cast on line 9 in Mainc.cpp invalid.

This is not going to be an easy thing to fix. However, I will make one suggestion to you (kind of related):

Use dynamic_cast<> instead of static_cast<> for polymorphic "downcasting". This will actually cause the compiler to generate code to ensure the cast is legal. Had you done this on the above code, an exception would have been thrown on line 9.

(Note: if you dynamic_cast to a pointer, NULL is returned if the cast fails. if you dynamic_cast to a reference, an exception is thrown on failure instead).


"This means that the compiler is "splicing" your parameter into two pieces -- the Object part and "the "rest" -- and it is copying ONLY THE Object PART into the array." -->

This means that i have to make an array for holding references to objects.

But a bit of look here and there...got to know that creating array for holding references is not possible in c++.

so, what can be the possible solution to it?

amal
Probably pointers are your only option, but that could be a fairly significant change to your application.
Topic archived. No new replies allowed.