multiple definitions error in c++ and solution to solve this issue - c++

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.
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)?
I have declared and defined a class in header file. Is this case the same as above (mentioned in 1)?
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?

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.

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:
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.
This is OK, as long as you define the member functions separately in the .cpp file.
No, see 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

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.

Related

Why can a static member function only be declared static inside the class definition and not also in its own definition?

While implementing a class for creating/updating boxes on the screen, I wanted to add a static member function that makes sure no currently visible boxes overlap (taking its information from a static pointer array to all currently visible boxes)
My initial code had the following structure:
class Box
{
public:
// ...
static void arrangeOverlappingBoxes();
};
static void Box::arrangeOverlappingBoxes()
{
// ...
}
I was quite surprised that this generated an error C2724: 'static' should not be used on member functions defined at file scope.
With some trial, google and error, I figured out that my function definition should lose the keyword static, i.e. it should be
void Box::arrangeOverlappingBoxes()
{
// ...
}
Yet I have no clue what the rationale behind this could be. It appears to be so asymetric and confusing to have a different function header for its declaration in the class definition and its own definition. Is there any reason for this?
Your class definition (in the header file) will provide the function with whatever propreties are necessary :
static
inlined
virtual
Considering that every further object will look at your class definition using the .h then it makes sense that these properties to be defined there.
Furthermore, each function from the class will mentain it's property in the derived classes (for example you need to declare the destructor virtual only in your base class, every subsequent inheritance will take the destructor as virtual).
It makes no sense to redeclare these properties in your implementation body .
Having to declare function proprieties in both .h and .cpp files would actually lead to allot of problems.
Imagine this scenario : you declare a function as virtual in a .h file, and as static in the .cpp file. What will the compiler make that function ? virtual or static ? (or more likely a compile error , but the compiler error will just urge you to match in your .cpp file the declaration in the header. You cannot overload a function according to "static" or "virtual").

Is it okay to provide the definition of a constructor inside the header file that declares it?

I am fairly new to C++, and I am sorry if this has been asked before but I did find a relevant answer. I know that it is poor practice to define methods inside header files, unless they are class templates in which they has to be defined inside the header file. How about for constructors? For example, I define empty constructors in .h files like so:
bmd2FileException(const std::string & _description) throw() : bmd2Exception(_description) {}
I also have an overloaded constructor which has a non-empty definition:
bmd2FileException(const std::string & _description, const char *, long int) throw() {
// do stuff
}
Do I need to include a seperate .cpp file for one or the other, or both constructors?
Thank you!
Yes, you can define constructors in the header file, typically inside the class definition itself as you have been doing.
No, it isn't necessarily poor practice. For example, it is probably silly to create a cpp file just to put the constructor definition somewhere other than the header, if the constructor is short and simple.
Edit: What you mention in your comments section about compiler errors about multiple definitions of the same function is true, but the situation where you define a class member method in the class definition is an exception.
Generally, your .h file is an interface file which means it just shows the methods you have but doesn't actually implement them. If you do want to do a .h and a .cpp file for one of your classes, you should probably implement your methods in your .cpp file instead of your .h file, as that is what the files were intended to be used for.
One reason you may not be able to implement functions in your constructors is that if two files need to include each other, you cannot have implementations in the headers.

Defining member functions of a class?

I am working with a book on c++ and to solve the problems I am always asked to declare the member functions' prototypes in the xxxxxx.h file and define the functions body properly in the xxxxxx.cpp file. Is there any harm or disadvantage in defining the member functions in the .h file? If not, is there any benefit or advantage in defining them in the .cpp file?
If you will always write your code in .h files you will never be able to performa some technics, such as forward declaration. Since you can't use forward declaration if writing code in headers you will be not able to solve cross dependencies.
So you will need to include everything you need in .h file. Including this file in other file will include everything already included. Thus any small change in you code will result in almost full recompilation in many cases.
Also it's harder to read the code in .h files because you expect to see the interface of the class in .h, not implementation.
If you define the method in the header, you have to mark it as inline or define them inside the class definition to prevent multiple definitions:
//A.h
class A
{
void f()
{
}
void g();
};
inline void A::g()
{
};
Other than that, it's a matter of coding style. You generally keep your headers clean, as to only provide an interface to work with the class, and abstract away the implementation details.
Generally. There are cases where you have to define the functions in the header (templates) or when you want to (to allow better compiler optimizations).

Member function definition

What is the right approach to take:
Define the member (class) function inside the class?
Define the member (class) function outside the class?
Thanks.
Assuming you're talking about these three possibilities:
Method defined in class definition in header file.
Method define outside class definition in header file.
Method define outside class definition in implementation file.
Then project and company guidelines may force you to use (1) or (3) always.
When you have a choice, it's IMHO best to adapt to circumstances at hand, considering things such as
Do you want a header-only module? Then (1) as default, (2) possible.
Is the method a large beast? Then (2) or (3).
Template method specialization? Then (2) or (3).
There is a build-time problem (slow builds)? Indicates (3).
Template class? (1) or possibly (2)
But except where the choice is effectively forced on you, above all consider the clarity of your code.
Cheers & hth.,
A common advice is to keep headers as simple and clean as possible. Headers will be included by external code, and they will have to process everything that you have written there. If you write a method in the header, all translation units will compile that function, only so that the linker can discard all but one of them later on.
If your code has an internal dependency on a type or library that is not part of your interface, then by inlining the code of the member function in the class declaration the definition of that class or the headers of that library will have to be included in your header, and that means that you are leaking your implementation details to your users.
Unless the member function definition is trivial (in an informal sense) and doesn't introduce any additional dependencies I would normally define a member function outside of the class body in a separate source file.
It's often a matter of style but there are some cases in which it is necessary and many other cases in which it is desirable to define function outside of the class body.
For example, in the cases where you have interdependent classes and only a forward declaration of another class can be made available before the class definition, a member function which uses the definition of that other class can only be defined outside of the class body after a full definition of the other class has been provided.
Do you mean "in the class declaration / .h file" vs "in a .cpp file using ::" ?
If so I always go for the latter. When it comes to debugging, it's a lot easier to step through and see what's going on. It also helps declutter the class declaration, which doesn't need to know any implementation details"
If you want to define a function within a class the most basic syntax looks generally like:
class Object
{
int property;
void doSomething()
{
property=100;
}
};
If you want to define a function outside it is similar to declaring functions before main and in library files. In your class you have:
class Object
{
int property;
void doSomething();
};
Then somewhere after your class, after the main() function or in an included file you can have the definition:
void Object::doSomething()
{
property=100;
}
Some place classes in a header file and the definitions in a cpp file used by that header. Various techniques possible.
Both of these approaches are valid. Often I will include very small and/or core class functionality directly within the class and other functions which do heavier bulk work I tend to separate. Try to think the difference in coming upon your code and wanting to alter it.
if we see according to performance issue than it is more effective way to declare the function in the class . becouse at the compile time it conects all the funcation calls and other components so it will easy and must be faster to get all in one source...

Anonymous Namespace Class Definition

I was looking over some (C++) code and found something like this:
//Foo.cpp
namespace
{
void SomeHelperFunctionA() {}
void SomeHelperFunctionB() {}
void SomeHelperFunctionC() {}
//etc...
class SomeClass //<---
{
//Impl
};
}
SomeHelperFunction[A-Z] are functions that are only needed in that translation unit, so I understand why they're in an anonymous namespace. Similarly, SomeClass is also only required in that translation unit, but I was under the impression that you could have classes with identical names in different translation units without any sort of naming collisions provided that you didn't have a global class declaration (e.g., in a commonly included header file).
I should also mention that this particular translation unit does not include any headers that might declare a class with an identical name (SomeClass).
So, given this information, could someone please shed some light on why the original programmer might have done this? Perhaps just as a precaution for the future?
I'll be honest, I've never seen classes used in anonymous namespaces before.
Thanks!
An anonymous namespace is like the static keyword when it is applied at the global level.
An anonymous namespace makes it so you can't call anything inside the namespace from another file.
Anonymous namespaces allow you to limit the scope of what's within to the current file only.
The programmer would have done this to avoid naming conflicts. No global names will conflict in this way at linking time.
Example:
File: test.cpp
namespace
{
void A()
{
}
void B()
{
}
void C()
{
}
}
void CallABC()
{
A();
B();
C();
}
File: main.cpp
void CallABC();//You can use ABC from this file but not A, B and C
void A()
{
//Do something different
}
int main(int argc, char** argv)
{
CallABC();
A();//<--- calls the local file's A() not the other file.
return 0;
}
The above will compile fine. But if you tried to write an CallABC() function in your main you would have a linking error.
In this way you can't call A(), B() and C() functions individually, but you can call CallABC() that will call all of them one after the other.
You can forward declare CallABC() inside your main.cpp and call it. But you can't forward declare test.cpp's A(), B() nor C() inside your main.cpp as you will have a linking error.
As for why there is a class inside the namespace. It is to make sure no external files use this class. Something inside the .cpp probably uses that class.
If someone links this code and has the definition of an identical named class included and this file is linked before the other implementation you would have a name conflict.
In the C++ ISO standard (Section 2.3), you will find a rule called The One Definition Rule.
Due to the complex relationship in C++ between compilation and linking, this is not a very simple rule. Most of the details are here.
But it applies to the functions that are members of a class, because they are (at the linking level) simply functions with long names.
It applies in a slightly different way to templates, because the linker will happily discard extra definitions of template classes or functions that appear in separate translation units (source files). This means that if you provide two different definitions of the same template, your program has undefined behaviour (best case scenario: one of the definitions will be silently chosen at random).
I was under the impression that you could have classes with identical names in different translation units without any sort of naming collisions provided that you didn't have a global class declaration
Well, that's not the case. Remember that those "common" global class definitions are in header files. Those are literally included, copying that common global class definition to all translation units. If you use another way of including exactly the same class definitions in multiple translation units (eg. macro expansion), it's fine too. But if you have different definitions for the same class name, you risk undefined behavior. Link failures if you're lucky.
To answer your question directly, I think that this is to avoid linker "multiple definition" errors for static members of SomeClass. That is, suppose SomeClass is defined in a cpp file without an anonymous namespace and there are some static fields and/or static methods in it and these static members are defined next to the class definition in this very cpp-file. Then these static members get the external linkage (are present in the symbol table of the corresponding .o file as GLOBAL).
Now you have another cpp-file and you want to create another SomeClass (unrelated to that one in the first cpp-file and you may be even unaware of the existence of the first SomeClass in that first cpp-file) for your own purposes and again without an anonymous namespace. And you define a static member with the same name as a static member of the first SomeClass. And here you are: you end up with a linkage conflict.
So the author of the first cpp-file should have hidden the first SameClass inside an anounimous namespace, as the class was clearly supposed to be an implementation detail, rather than a class re-used by other people. And so its static members should not have external linkage.
So overall, what I try to say is that non-constexpr/non-inline static members of a class are just like global variables or non-inline functions. And so their linkage can be made internal using an anonymous namespace just like it can be done for global variables and functions using static keyword or again an anonymous namespace.
// .cpp file
namespace
{
struct A
{
static int i;
};
}
int A::i;