error : multiple definition of constructor - c++

Can you please help me to know how I can avoid the error..
Thanks in advance.
file name: point.hh
#ifndef POINT_H
#define POINT_H
class Point{
private:
int x;
int y;
public:
Point();
};
#endif
file name:point.cc
#include "point.hh"
#include <iostream>
using namespace std;
Point::Point()
{
x=0;
y=0;
cout<<"x="<<x;
cout<<"y="<<y;
}
file name: main.cc
#include"point.cc"
int main()
{
Point p; // calls our default constructor
}

You must include the header file, not the source file, in your main.cc file to use the Point class.
That is, replace:
#include"point.cc"
By:
#include"point.hh"
The rationale behind this is that a function definition, unless marked inline, must respect the ODR ("One Definition Rule"). By including the source file in your other source file, you end up having two (identical) definitions of the Point::Point() function in two different translation units.
When the linking process takes place, it sees this two definitions and complains: that is the error you get.

Another cause is the build command, if you have the same .cpp file listed twice you will definitely get this error and it will say that functions you didn't even write have the error.
Might help someone in the future.

Related

Is it safe to separate your templated class' declaration and definitions on different header files?

I'm trying to create a library for a school work, and I've been wondering if it is safe to declare a templated class on the main header file containing the class definition and method declarations, but then separating the method definitions in a different header file?
Because I have been able to do this in my example below, but I don't know if it will cause me some problems in the long run.
main program
// main.cpp
#include <iostream>
#include "declaration.hpp"
int main()
{
card<int> a(5);
std::cout<<a.getID()<<'\n';
return 0;
}
main header file
in this header file, only the class definition and the declaration of the method getID() is written but not it's definition, and by the end of the class I included the other header file that contains the method definitions.
// declaration.hpp
#ifndef DEC_HPP
#define DEC_HPP
#include <iostream>
template<typename T>
class card
{
public:
T id;
card(const int id) : id(id) {}
T getID();
};
#include "definition.hpp"
#endif
method definitions
This header file contains the method definition of getID() from the main header.
I also included the "declaration.hpp" in this header, and this is the part where I'm not so sure of, because I included both files together with each other.
// definitions.hpp
#ifndef DEF_HPP
#define DEF_HPP
#include <iostream>
#include "declaration.hpp"
template<typename T>
T card<T>::getID()
{
return id;
}
#endif
I have compiled this program and it's working on my machine, but I just wanted to know if this way of isolating my code will cause me some errors in the future, I don't want to put my templated class definitions in a cpp files because I find it hard to maintain.
This is indeed a better approach because it makes your code look simple and better. Moreover, it is the main reason why header file is used.
Your main header file will simply tell that what functions/classes are you using and without even viewing your code, anyone can guess if you are working correctly or not.
There wont be any safety issues at all.

C++ defining same function twice causes error

I'm too much confused why it's an error to write the same function in two different cpp files?
what if both want to use that function? and why this should ever cause an error, the function is written in to separate files...
a.cpp:
#include "test.h"
b.cpp:
#include "test.h"
test.h
int getMin(int x,int y)
{
return x;
}
plus, why changing test.h to the following won't fix the problem:
#ifndef UNTITLED1_A_H
#define UNTITLED1_A_H
int getMin(int x,int y)
{
return x;
}
#endif
If you define a function twice, the linker will see 2 definitions of the same function, which is not allowed. (even though each .cpp that includes this header file sees only one definition, which is why adding header guards doesn't help here).
One option is to only write the declaration of the function in the .h file, and write the definition in a separate .cpp file. (this is the more common implementation).
If you want to define the function inside the header file, then it needs to be inline, like this:
inline int getMin(int x,int y)
{
return x;
}
Note that if you do the second option, then all files that include this header will need to be recompiled, if you change the internals of this function (this is probably not a good idea, when the interface doesn't change).
You need to make this function "inline" and it will work.

Instant object initialization in C++ fails with LNK2005 error

These are the errors that I've been receiving:
LNK2005 "class Sally TestObject" (?TestObject##3VSally##A) already defined in Source.obj Project2 c:\Users\W8User\documents\visual studio 2015\Projects\Project2\Project2\Source1.obj
and
LNK1169 one or more multiply defined symbols found Project2 c:\users\w8user\documents\visual studio 2015\Projects\Project2\Debug\Project2.exe
I don't really understand where are these errors coming from. I've tried searching in other SO threads or on the connected Microsoft's website, but none helped.
These are my files:
Source.cpp
#include <iostream>
#include "Header.h"
int main() {
std::cout << TestObject.ReturnTruth();
return 0;
}
Header.h
#pragma once
class Sally
{
public:
bool ReturnTruth();
} TestObject;
Source1.cpp
#include "Header.h"
bool Sally::ReturnTruth()
{
return 1;
}
What I know is that it's enough to move the object initialization into the Source.cpp file and not do it instantly in the header file, but since the instant initialization is a possibility then why wouldn't I use it?
Let's suppose that you have two different .cpp files that each include your Header.h header. Then, each one of those .cpp files gets this code incorporated into it:
class Sally
{
public:
bool ReturnTruth();
} TestObject;
As a result, each file contains the definition of an object named TestObject of type Sally. This breaks the one-definition rule, since there's only supposed to be at most one definition of each object across all translation units, and it's manifesting in your linker error.
If you do want to declare a global object of type Sally, change the header to declare an extern object of type Sally, like this:
class Sally
{
public:
bool ReturnTruth();
};
extern Sally TestObject;
This is a declaration, not a definition, and it's okay to have redundant declarations of objects.
Then, pick a .cpp file - probably the one where you implement the Sally member functions - and add this line:
Sally TestObject;
That puts the definition of the object in a single place, and so fixes the one-definition-rule issue and the linker issue.
Every single place you #include "Header.h" you will have an instance of TestObject, and unless your compiler can fold all of these into a singleton you're going to have several independent, unrelated instances.
That error is advising you that you've made a mistake. One way to fix this is to define in the header file:
extern Sally TestObject;
Which makes it explicitly clear that this will be instantiated elsewhere. Then make an explicit instance in Source1.cpp:
Sally TestObject;
Then your main file will know where to look for this thing.
It's not clear if you want a singleton in the first place. Why can't you just instantiate one inside of main and use it?
As a note, please, please take the time to give your source files meaningful names.
By appending identifier TestObject directly after the class definition Sally, you define a variable in your header file. So if different translation units include this header file, a variable with the same name is defined twice, leading to a linker error. You can resolve this by just declaring the variable, i.e. using extern-keyword in the headerfile, whereas defining the variable then in exactly one .cpp-file:
So write:
Header.h
class Sally
{
public:
bool ReturnTruth();
};
extern Sally TestObject;
Source1.cpp
#include "header.h"
Sally TestObject;
...
in all other CPP-files:
#include "header.h"
...

How to Include-guard when using multiple headers on a main.cpp?

I'm learning C++ in a course, using Visual Studio 2013, and I have an issue with include-guards on my main.cpp. I can't use either class or #pragma once (though they work) due to conditions my professor said.
If I only use Coordinates and Line, and I use in main.cpp the #include Line.h (which get code from both Line and Coordinates), this works ok, but when I add Rectangle and Triangle (both have #include "Line.h"), then it throws the "already defined" error LNK2005 several times.
Is there something missing?
This is my code:
Coordinates.h
#ifndef Coordinates
#define Coordinates
//Code declaration. Other headers have similar declaration
struct CoordinatesType { double x, y; } coordinates;
void setCoordinates(double x, double y);
CoordinatesType getCoordinates();
#endif
Coordinates.cpp
#include "Coordinates.h"
//Code implementation
Line.h
#ifndef Line
#define Line
#include "Coordinates.h"
//Code declaration
#endif
Line.cpp
#include "Line.h"
#include <math.h>
//Code implementation
Rectangle.h
#ifndef Rectangle
#define Rectangle
#include "Line.h"
//Code declaration
#endif
Rectangle.cpp
#include "Rectangle.h"
//Code implementation
Triangle.h
#ifndef Triangle
#define Triangle
#include "Line.h"
//Code declaration
#endif
main.cpp
#include "Triangle.h"
#include "Rectangle.h"
int main(){
//Do stuff here.
}
If you need me to add the implementation and declaration codes, let me know, but I feel like it has to do with the include-guard.
EDIT: I'll add code in the Coordinate header so you can get an idea of what I'm doing and to avoid consuming a lot of space in the post. Remember, I can't use class Coordinates{} due to my professor's restriction to not use it.
This error is a linker error, not a compiler error.
Header guards do nothing for the linker.
You have successfully guarded against multiple declarations of things within the same translation unit, but you have not guarded against multiple definitions of things across your whole program.
The way to guard against that is to, well, not do that. There should be no non-inline, non-template definitions of anything in your header if you want to include it into multiple source files.
Here, you declare a type CoordinatesType, and create an object of that type:
struct CoordinatesType { double x, y; } coordinates;
Don't do that! Create an instance of CoordinatesType only in a source file, not in a header. Otherwise, every source file that includes this header (directly or indirectly) will get its own coordinates object and your linker complains about the name collision.
The code should be:
struct CoordinatesType { double x, y; };
Then, either coordinates in the one source file in which you wish to use the object… or extern on its declaration in a header. There are better approaches but I shan't enumerate them all here since this topic has been covered to death on SO already. Furthermore, your C++ book will have an explanation.
But the long and short of it is that this has nothing to do with header guards.
As already pointed out, your problem has nothing to do with include-guards.
Your problem is in this line:
struct CoordinatesType { double x, y; } coordinates;
While the declaration of the struct
struct CoordinatesType { double x, y; };
may appear in multiple .cpp files, as long as it is identical (it is, since you include the same header-file), you also define a variable
CoordinatesType coordinates;
in the same line. Since a definition is only allowed once, your linker complains.
If you really need a global variable of that type (check if you really need one, as it might not be necessary), change your header to a declaration:
struct CoordinatesType { double x, y; };
extern CoordinatesType coordinates;
and use a definition
CoordinatesType coordinates;
in exactly one cpp-file.
Note that the error didn't happen when only including Line and Coordinates, because your include-guards work and you only include the headers in a single .cpp file
Coordinates.h doesn't have any include guard.
When you include it multiple times, it defines Coordinates only once, but the rest of the file is included multiple times.
Put the #endif in the right place.
PS. The identifiers used in the include guards should be something that is never, ever used elsewhere by coincidence. I wouldn't be surprised if someone tried to use a variable named Line or Triangle. And since you #define those, that will lead to very unexpected errors. Use something like #define LineHeader_Included__ .

Header files. etc

I defined a simple class. The definition is in the header file and the implmentation is in the cpp file:
HEADER:
#ifndef POINT_H
#define POINT_H
class Point {
public:
Point(int x, int y);
int getX();
int getY();
private:
int x, y;
};
#endif
CPP
#include Point.h
Point::Point(int x=2, int y=2) {
this->x = x;
this->y = y;
}
int Point::getX() {
return x;
}
int Point::getY() {
return y;
}
This is not compiling and I am not sure why. Also, when I want to instantiate a point
somewhere else, say main.cpp, what do I #include at the top, just Point.h? If so, how does it know to look in Point.cpp?
#include Point.h
You need quotes around Point.h.
Point::Point(int x=2, int y=2)
The default arguments should be in the declaration in the header file, not in the definition in the .cpp file (it will compile as-is, but won't do what you want).
On a stylistic note, it's usually a bad idea to name local variables or arguments the same as member variables: doing so can easily lead to confusion. You can also initialize member variables using an initializer list:
Point::Point(int x_, int y_) : x(x_), y(y_) { }
As your code is currently written, x and y are both constructed, then you assign to them. Using an initializer list eliminates the assignment and just constructs them directly. This doesn't matter for fundamental types like int, but it does matter for class types.
This is not compiling and I am not sure why.
Usually the error message that the compiler issues is helpful. If nothing else, if it isn't helpful to you, it's helpful to those of us trying to help.
Also, when I want to instantiate a point somewhere else, say main.cpp, what do I #include at the top, just Point.h?
Yes.
How does it know to look in Point.cpp?
Each .cpp file that you write gets compiled into a separate object file. Once all the .cpp files are compiled into object files, the object files all get linked together into an excecutable (or a library). The linker figures out where everything is defined.
You are missing quotes in your include
#include "Point.h"
In the file where you want to instantiate a Point you must include Point.h
You should put the argument defaults in the header although without the error message I can't say if this is your problem. Also you should quote your include #include "Point.h"
You defined default values for x and y in the implementation. This can't work. Think a bit how this is supposed to work if the clients of your class only see the header and hence have no idea that they could possibly call Point without default parameters?
The trick is that the implementation is compiled into your application, and calls get resolved using the declaration only (the stuff in the header). For each call, the compiler creates a symbol name and marks the call (for instance, when you call Point::getX, the compiler will insert call which looks like call _getX#Point#). The linker, which comes after the compiler will search for this function. If it's implemented, it will be found and the caller will get "redirected" to the Point::getX() source code.
[Edit] Oh and you need to write #include "Point.h".
What is the error you're getting?
You just include the .h file:
#include "Point.h"
The linker resolves the references to code when it builds the executable.