multiple definitions error in c++ and solution to solve this issue [duplicate]
Asked Answered
J

5

9

I am new to C++. I have some doubts regarding multiple definitions error in C++.

Let's say I have 3 files in a program. One header file and 2 .cpp files. I have included the header file in both the .cpp files.

  1. I have declared a class in the header file and I have defined the class in each of the .cpp files in exactly the same way. So will this type of implementation cause multiple definitions error? If so, is it because it has two copies of class definitions and the compiler doesn't know which one to take during linkage of two .o files?

Can we solve this problem by using extern in header file and defining the class in only one of the files?If we can solve the issue by using this method,do we have to include the .cpp(with class definition) into other .cpp file(with no class definition)?

  1. I have declared and defined a class in header file. Is this case the same as above (mentioned in 1)?

  2. I have declared a class in the header file and I have defined the class in each of the .cpp files but the definitions (function bodies)differs. So will this type of implementation causes multiple definitions error? If so, how can we solve this problem where the functions bodies differs in the .cpp files?

Jampan answered 20/9, 2013 at 10:7 Comment(0)
N
15

1) You solve this by 'defining the class' in only one cpp file. Why would you want to define it in two files?

2) Don't define things in header files, only declare them. There are exceptions to this rule, for instance inline functions. Also classes themselves can defined more than once (by this I mean declaring the methods and data members of the class, (i.e. writing class XYZ { ... };) but each definition must be identical. The simplest way to achieve this is to define a class once in a header file. Then each definition resulting from including that header file in multiple places will necessarily be identical.

3) This one is even sillier, it's one thing to define somethiing twice, but define it twice and differently each time makes even less sense.

I guess the issue is why you think it might sometimes be necessary to define things more than once. Don't do that.

You should also make it clear what you mean by 'define the class'. I've taken that to mean define the methods and static members of the class. But if you have something else in mind that might be a source of confusion. As usual the best way to avoid this kind of terminology confusion is to post some code.

Namnama answered 20/9, 2013 at 10:18 Comment(5)
Well, the class definition is usually put in a header, though the standard requires it to be identical in each translation unit. What you say pretty much holds for the definition of each (non-inline) function, but not the class itself.Paleography
@Paleography I'm unsure what the OP means by 'defining the class'. As I said in my answer I assumed he meant defining the methods of the class.Namnama
After reading it an extra time, I believe he actually meant the class definition. Whether he realizes the difference between this and also defining the member functions, I cannot say. However, your answer clearly states (in rather harsh words), that you shouldn't define a class in a header file, which is incorrect.Paleography
@Paleography 'rather harsh words' I get frustrated, and one of the things that makes me frustrated is the reluctance of people to post code when asking questions about their code.Namnama
I understand what you mean. And I agree this question is a bit too fuzzy. What I mean, though, was that if someone would read your answer after briefly looking over the question, you state clearly that classes shouldn't be defined in header files. This is not the case, so I suggest trying to reformulate it somewhat?Paleography
P
6

To answer all of these questions, you only need to look at the purpose of declarations and definitions.

Declarations of a class simply state that the class exists and in which context. For a class, a simple forward declaration (e.g. class Banana;) allows you to use pointers or references to that class, but that's it.

Definitions state exactly what the class is. That is, which members it has and from what base classes it is derived. You need this available whenever you access members of the class, or need to know the size of its instances. This means the class definition needs to be put in a header file, so that it can be included wherever in all files which use the class. This is OK, because the standard says that a class can be defined in multiple translation units, as long as all definitions are identical.

A class definition typically looks something like this:

class Banana
{
public: 
  Banana(){}

  void eat();

private:
  //....
};

However, please note that this class definition only means the definition of the class itself, not the non-inline member functions. Such as void eat() in the above example. These need to be defined in the .cpp file, because they may not be defined in multiple translation units.

So in short:

  1. This is not right, only define it in the header file and define non-inline member functions in the matching .cpp file. You should never define the same function or type in more than one file.
  2. This is OK, as long as you define the member functions separately in the .cpp file.
  3. No, see 1.
Paleography answered 20/9, 2013 at 10:49 Comment(0)
M
1

1) You can't have two definitions of the same class in your project. And I have no idea how you plan to use it. If you want to make instances of one class with different behavior, use virtual function like:

class A {
public:
    virtual int foo() = 0;
}

class B : public A {
public:
    virtual int foo() { return 1; }
}

class C : public A {
public:
    virtual int foo() { return 2; }
}

2) You may define class in header file (java-style), but it's not the best idea because compiler will consume more resources to build other files, include this header. Let compiler work fast - define classes in .cpp files.

3) See p.1

Marco answered 20/9, 2013 at 10:22 Comment(0)
S
1

There's no problem with defining a class in several places. That's exactly what happens when you put the definition in a header and #include that header in more than one source file. However, note that defining a class means writing out what the class contains, not defining its members. This is a class definition:

class C {
    void f();     // member function declaration
    void g() { }  // member function declaration with inline definition
    int i;        // member declaration
    static int j; // member declaration
};

like most things, you can't define it more than once in a single source file. However, it can appear in as many source files as you like, provided only that it's the same everywhere.

This class definition declares two members that must be defined somewhere, typically like this:

void C::f() {
    std::cout << "In C::f\n";
}

int C::j = 3;

These definitions can appear only once in the entire program; usually each is defined once in a source file.

Streetlight answered 20/9, 2013 at 10:50 Comment(0)
E
0

I would suggest to to use class in header file and write your functions within it. If you use static functions so that it could be called without any instance.

For example, define class con and function ftoa() in header file ftoa.h

class con
{
   static string ftoa()
   {
   }
};

Now you can use header file and call function by con::ftoa (), without creating any instance of class (objects).

Eversion answered 14/7 at 3:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.