John Lannister John Lannister - 25 days ago 10
C++ Question

C2371 Error: redefinition; different basic types

So, I am making a project for my university, and I get the error stated in the title. here is my code.

//components.h
#ifndef COMPONENTS_H
#define COMPONENTS_H
#include <stdlib.h>
#include <string>
#include <iostream>
#include <Windows.h>

#define GRAY 8
#define BLUE 9
#define GREEN 10
#define CYAN 11
#define RED 12
#define PURPLE 13
#define YELLOW 14
#define WHITE 15

using namespace std;

template <class TYPE> class NODE
{
public:
NODE()
{
next = NULL;
prev = NULL;
}
TYPE data;
NODE<TYPE> *next, *prev; //next and previous nodes
};

template <class TYPE> class LIST {
private:
NODE<TYPE> *head, *tail;
public:
int count;
LIST()
{
head = NULL;
tail = NULL;
}
~LIST()
{
EmptyList();
}

NODE<TYPE>* GetElement(int n)//find nth element
{
if (n > count)
return NULL;
else
{
NODE<TYPE> *temp = NULL;
if (n < (count / 2))
{
temp = head;
for (int i = 0; i < (n - 1); i++) {
temp = temp->next;
}
}
else
{
temp = tail;
for (int i = 0; i < (count - n - 1); i++) {
temp = temp->prev
}
}
return temp;
}
}

void PushBack(TYPE data)
{
if (head == NULL)
{
head = new NODE<TYPE>();
head->data = data;
tail = head;
}
else
{
NODE<TYPE>* temp = new NODE<TYPE>();
temp->data = data;
temp->prev = tail;
tail->next = temp;
tail = tail->next;
}
count++;
}

void PopBack()
{
if (tail->prev != NULL)
{
tail = tail->prev;
delete tail->next;
tail->next = NULL;
}
else
{
delete tail;
head = NULL;
tail = NULL;
}
count--;
}

void EmptyList()
{
while (head != NULL)
PopBack();
}
};

class PARTICLE {
protected:
double mass;
float spin;
double electric_charge;
string statistics;
string name;
public:
double getElectricCharge()
{
return electric_charge;
}
void printMass() { cout <<name<<" mass: "<< mass <<"u"<<endl; }
void printSpin() { cout <<name<<" spin: "<< spin << endl; }
void printElectricCharge() { cout <<name<<" electric charge: "<< electric_charge <<"e"<<endl; }
void printStatistics() { cout <<name<<" statistics: " << statistics << endl;}
};

class ELECTRON : public PARTICLE {
public:
ELECTRON()
{
name = "Electron";
mass = 0.000548579909070;
spin = 0.5f;
electric_charge = -1;
statistics = "Fermi-Dirac";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CYAN);
cout << "A(n) " << name << " has been constructed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
~ELECTRON()
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), CYAN);
cout << "A(n) " << name << " will be destroyed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
};

class GLUON : public PARTICLE {
public:
GLUON()
{
name = "Gluon";
electric_charge = 0;
spin = 1;
statistics = "Bose-Einstein";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), GRAY);
cout << "A(n) " << name << " has been constructed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
~GLUON()
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), GRAY);
cout << "A(n) " << name << " will be destroyed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
};

class UP_QUARK : public PARTICLE{
public:
UP_QUARK()
{
name = "Up Quark";
electric_charge = 2.0/3.0;
mass = 2.01;
spin = 0.5f;
statistics = "Fermi-Dirac";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), GREEN);
cout << "A(n) " << name << " has been constructed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
~UP_QUARK()
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), GREEN);
cout << "A(n) " << name << " will be destroyed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}

void printQuarkMass()
{
cout << name << " mass: " << mass <<" MeV/(c^2)"<<endl;
}
};

class DOWN_QUARK : public PARTICLE {
public:
DOWN_QUARK()
{
name = "Down Quark";
electric_charge = -(1.0 / 3.0);
mass = 4.7;
spin = 0.5f;
statistics = "Fermi-Dirac";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), PURPLE);
cout << "A(n) " << name << " has been constructed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
~DOWN_QUARK()
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), PURPLE);
cout << "A(n) " << name << " will be destroyed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}

void printQuarkMass()
{
cout << name << " mass: " << mass << " MeV/(c^2)" << endl;
}
};

class PROTON : public PARTICLE{
private:
LIST<DOWN_QUARK*> dqList;//1
LIST<UP_QUARK*> uqList;//2
LIST<GLUON*> gList;//3
public:
PROTON()
{
dqList.PushBack(new DOWN_QUARK);
uqList.PushBack(new UP_QUARK);
uqList.PushBack(new UP_QUARK);
gList.PushBack(new GLUON);
gList.PushBack(new GLUON);
gList.PushBack(new GLUON);

name = "Proton";
mass = 1.007;
electric_charge = 1;
spin = 0.5f;
statistics = "Fermi-Dirac";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
cout << "A(n) " << name << " has been constructed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}

~PROTON()
{
dqList.EmptyList();
uqList.EmptyList();
gList.EmptyList();
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), YELLOW);
cout << "A(n) " << name << " will be destroyed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
};

class NEUTRON : public PARTICLE{
public:
LIST<DOWN_QUARK*> dqList;//2
LIST<UP_QUARK*> uqList;//1
LIST<GLUON*> gList;//3

NEUTRON()
{
dqList.PushBack(new DOWN_QUARK);
dqList.PushBack(new DOWN_QUARK);
uqList.PushBack(new UP_QUARK);
gList.PushBack(new GLUON);
gList.PushBack(new GLUON);
gList.PushBack(new GLUON);

name = "Neutron";
mass = 1.0085;
spin = 0.5f;
electric_charge = 0;
statistics = "Fermi-Dirac";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BLUE);
cout << "A(n) " << name << " has been constructed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
~NEUTRON()
{
dqList.EmptyList();
uqList.EmptyList();
gList.EmptyList();
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BLUE);
cout << "A(n) " << name << " will be destroyed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
};

class NUCLEUS {
public:
NUCLEUS();
~NUCLEUS();
LIST<PROTON*> pList;
LIST<NEUTRON*> nList;
};

class ATOM { //<================ ERROR APPEARS HERE
public:
ATOM();
~ATOM()
{
nList.EmptyList();
eList.EmptyList();
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), RED);
cout << "An Atom has been destroyed\n";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
}
int getMassNumber();
void printMassNumber();
int getAtomicNumber();
void printAtomicNumber();
double getElectricCharge();
void printElectricCharge();
LIST<NUCLEUS*> nList;
LIST<ELECTRON*> eList;
private:
int mass_number;
int atomic_number;
double electric_charge;
};

#endif


Could you help me figure out what went wrong? The error appears to be at line 304. I have attached a comment to the code as to make searching more painless :)

Answer

There is already an ATOM type in the Windows APIs, therefore you are getting a conflict between the Windows ATOM type and your own ATOM class.

There are two possible solutions. First, you could rename your class. This would avoid the conflict with the Windows API and allow your code to compile, however this is probably less than ideal.

The other solution would be to wrap your classes in a namespace. This would allow you to keep your current name while also avoiding conflict with Windows. Example:

namespace MyNamespace
{

class ATOM { //<================ SHOULD COMPILE
public:
    ATOM();
    ~ATOM()
    {
        nList.EmptyList();
        eList.EmptyList();
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), RED);
        cout << "An Atom has been destroyed\n";
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), WHITE);
    }
    int getMassNumber();
    void printMassNumber();
    int getAtomicNumber();
    void printAtomicNumber();
    double getElectricCharge();
    void printElectricCharge();
    LIST<NUCLEUS*> nList;
    LIST<ELECTRON*> eList;
private:
    int mass_number;
    int atomic_number;
    double electric_charge;
};

}

In your code, you would create ATOM variables like this:

MyNamespace::ATOM myAtom;

As a personal rule, I tend to put all my own code inside of namespaces because it reduces the potential for conflicts like this, and I would recommend putting ALL your own classes inside their own namespace in general.