0

I've created 2 header files. ListA.h and ListN.h

They both make their own use their own unique class List. When I compile my program (even though they have no way of knowing the other exists, it says the following error)

enter image description here Im pretty sure it shouldnt be a redefinition, but it obviously is. Any help is appreciated.


ListA.h

#ifndef __LISTA_H_
#define __LISTA_H_
#include <iostream>

using namespace std;
class List{
        public:
              List(int = 0);
              List(const List&);
              ~List();
};   
#endif

ListN.h

#ifndef __LISTN_H_
#define __LISTN_H_
#include <iostream>

using namespace std;

class List{
        public:
              List(int = 10);
              List(const List&);
              ~List();
};    
#endif

ListA.cpp

#include "ListA.h"
using namespace std;

List::List(int mySize)
{
    //...
}

ListN.cpp

#include "ListN.h"
#include <iostream>
using namespace std;
List::List(int size)
{
    //...
}

Main

#include <iostream>
#include "ListN.h"
using namespace std;

int main()
{
    List myList;
    return 0;
}
Gunner Stone
  • 997
  • 8
  • 26
  • 1
    They're both in the same project, that _might_ have something to do with it. – Justin Time - Reinstate Monica Nov 29 '16 at 04:46
  • **[basic.def.odr]** "Given such an entity named D defined in more than one translation unit, then each definition of D shall consist of the same sequence of tokens..." You violated this rule by having an entity named `List` defined differently in different translation units. – Raymond Chen Nov 29 '16 at 13:57

2 Answers2

0

When linker trying to link find the definition / symbol for List, it does found in two different obj file and hence linker givers error. In visual studio error number : LNK2005

To solve this error, either:

  1. To fix, add /FORCE:MULTIPLE to the linker command line options
  2. Add the classes in two different namespaces which will avoid this error.

ListN.h

#ifndef __LIST_H_
#define __LIST_H_
#include <iostream>

using namespace std;

namespace ListN
{
  class List{
  public:
      List(int = 10);
      List(const List&);
  };
}

#endif

ListN.cpp

#include "ListN.h"
#include <iostream>

using namespace std;

namespace ListN
{
  List::List(int size)
  {
      //...
  }
}

Main.cpp

#include <iostream>
#include "ListN.h"
int main()
{
  ListN::List myList;
  return 0;
}
MSalters
  • 173,980
  • 10
  • 155
  • 350
Swapnil
  • 1,424
  • 2
  • 19
  • 30
0

Both cpp files are being compiled by the compiler. Thus, when the linker goes to link the files together, it gets confused, since there are multiple List classes.

To fix this, you could use namespaces, or you cold not expose at least one of the List classes.


Alternatively, if the idea was to be able to include ListN.h vs ListA.h for configuration purposes, this is the wrong way to do so. Either you should have a #define parameter for the header, or you should find some other way, such as through #ifdef. For example (I'm not 100% sure this would compile, but you get the idea):

List.h

#ifndef __LIST_H_
#define __LIST_H_

#ifndef LIST_PARAM
#define LIST_PARAM 0
#endif

#include <iostream>

using namespace std;

class List{
        public:
              List(int = LIST_PARAM);
              List(const List&);
              ~List();
};    
#endif

main.cpp

#include <iostream>

#define LIST_PARAM 10
#include "List.h"

using namespace std;

int main()
{
    List myList;
    return 0;
}

I personally don't like this method; it is much better to just pass the value in to the constructor:

int main()
{
    List myList{ 10 };
    return 0;
}
Justin
  • 24,288
  • 12
  • 92
  • 142