7

I'm almost 100% sure I have the syntax right in both of these classes, however I'm getting the following errors:

For CShape.cpp - "error C2011: 'CShape' : 'class' type redefinition" For CCircle.cpp - "error CS2504: 'CShape': base class undefined"

Here is the full code for CShape.cpp

#include <iostream>
using namespace std;

class CShape
{
protected:
    float area;
    virtual void calcArea();
public:
    float getArea()
    {
        return area;
    }
}

And here is the code for CCircle.cpp

#include <iostream>
#include "CShape.cpp"
#define _USE_MATH_DEFINES
#include "math.h"
using namespace std;

class CCircle : public CShape
{
protected:
    int centerX;
    int centerY;
    float radius;
    void calcArea()
    {
        area = M_PI * (radius * radius);
    }
public:
    CCircle(int pCenterX, int pCenterY, float pRadius)
    {
        centerX = pCenterX;
        centerY = pCenterY;
        radius = pRadius;
    }
    float getRadius()
    {
        return radius;
    }
}

As you can see, CShape is the base class that CCircle is suppsoed to inherit from. I'm pretty new to C++, so I could have the file structures wrong (maybe the base is supposed to be in a header file?), if something like that matters.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
NealR
  • 10,189
  • 61
  • 159
  • 299

2 Answers2

13

Never #include .cpp files; that will lead to the kind of redefinition errors you are getting. Instead, declare the class in a header file and #include that one, and define the class methods in a .cpp file.

// CShape.h
class CShape
{
protected:
    float area;
    virtual void calcArea();
public:
    float getArea();
}

.cpp file:

// CShape.cpp
#include "CShape.h"
#include <iostream>
using namespace std;

float CShape::getArea() {
    return area;
}

You should split up CCircle similarly - and CCircle.h should #include CShape.h, and CCircle.cpp should #include CCircle.h.

Moradnejad
  • 3,466
  • 2
  • 30
  • 52
Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
  • Thank you very much! In order to make a Circle, Triangle, Rectangle, etc class that extend the CShape class would it be best to include all those class definitions in the CShape header file then simply define the class methods in their respective .cpp files? Basically you'd just have one header file and a .cpp file for every shape you needed to create. – NealR Aug 04 '12 at 21:29
  • 1
    @NealR no, `CShape` shouldn't know anything about derived classes. The derived classes should include the `CShape` header. – juanchopanza Aug 04 '12 at 22:14
  • 1
    Indeed; the best practice is to have one .h and one .cpp file for each class. – Aasmund Eldhuset Aug 04 '12 at 22:33
5

As you guessed, you should organize your classes in separate files for declaration (header file) and definition (.cpp file). You may leave member function definitions (with body) as (suggested) inline in the header files. Put appropriate include blockers into your header files, to avoid multiple class declarations.

CShape.h:

#ifndef __CSHAPE_H__
#define __CSHAPE_H__
class CShape
{
protected:
    float area;
    virtual void calcArea();
public:
    float getArea()
    {
        return area;
    }
};
#endif

CShape.cpp:

#include "CShape.h"

void CShape::calcArea()
{
    // Your implementation
}

CCircle.h:

#ifndef __CCIRCLE_H__
#define __CCIRCLE_H__
#include "CShape.h"

class CCircle : public CShape
{
protected:
    int centerX;
    int centerY;
    float radius;
    virtual void calcArea();
    {
        area = M_PI * (radius * radius);
    }
public:
     CCircle(int pCenterX, int pCenterY, float pRadius);
     inline float getRadius()
     {
         return radius;
     }
};
#endif

CCircle.cpp:

#include "CCircle.h"

CCircle::CCircle(int pCenterX, int pCenterY, float pRadius)
: centerX(pCenterX)
, centerY(pCenterY)
, radius(pRadius)
{
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190