LINKER ERROR LNK1169 & LNK2005 [duplicate] - c++

This question already has answers here:
C++, good old LNK1169 (and LNK2005) errors
(3 answers)
Closed 5 years ago.
I'm learning c++ and trying to practice translation units and other things at once, but I'm getting the errors listed on the title. This program is for learning purposes and I've tried to explain what each header and implementation file is suppose to do.
--------CString.h--------
#ifndef CSTRING_H
#define CSTRING_H
#include <iostream>
namespace w1
{
class CString
{
public:
char mystring[];
CString(char cstylestring[]);
void display(std::ostream &os);
};
std::ostream &operator<< (std::ostream &os, CString &c)
{
c.display(os);
return os;
}
}
#endif
--------process.h-------- prototype for process function
void process(char cstylestring[]);
--------CString.cpp--------
To receive a C-style string in constructor and truncate it by taking the first three characters and storing it in mystring to be later displayed through the function display()
#include <iostream>
#include "CString.h"
#define NUMBEROFCHARACTERS 3
using namespace w1;
w1::CString::CString(char stylestring[])
{
if (stylestring[0] == '\0')
{
mystring[0] = ' ';
}
else
{
for (int i = 0; i < NUMBEROFCHARACTERS; i++)
{
mystring[i] = stylestring[i];
}
}
//strncpy(mystring, stylestring, NUMBEROFCHARACTERS);
}
void w1::CString::display(std::ostream &os)
{
std::cout << mystring << std::endl;
}
--------process.cpp-------- receives a C-style string and creates a CString object and then display the possibly truncated version of the c-style string by operator overloading.
#include "process.h"
#include "CString.h"
#include <iostream>
using namespace std;
void process(char cstylestring[])
{
w1::CString obj(cstylestring);
std::cout << obj << std::endl;
}
--------main.cpp-------- Testing purposes by sending a C-style string to process function.
#include <iostream>
#include "process.h"
using namespace std;
int main()
{
char themainstring[] = "hiiiii";
process(themainstring);
return 0;
}

The << operator is defined multiple time because you define it in an header file that is include from multiple source files.
Either add inline modifier so that only one copy will be kept or move the definition in one source file (and only keep the declaration in the header file).
As I have mentioned in my comment, the program would crash at run time because no memory is allocated for mystring. If it should be 4 characters long maximum, then you could simply add 4 inside the square bracket as in:
char mystring[4];
Otherwise, if you need variable size, then using something like std::vector might make sense as you would avoid explicit memory management.
Update:
My original answer was complete but since you don't seem to properly understand it, I have added extra details...
I am talking of the following definition in CString.h:
std::ostream &operator<< (std::ostream &os, CString &c)
{
c.display(os);
return os;
}
Both process.cpp and main.cpp include the file CString.h which contains that definition twice (once when compiling each of these 2 files).

Related

Undefined reference using namespace C++

When I want to run the code the compiler says undefined reference to math::calc
I read questions and answers about this problem at StackOverflow and it do not help me solve my problem.
Comp.h
#include <utility>
namespace math {
typedef std::pair<double,double> Comp;
double getFirst(Comp a);
...
}
Comp.cpp
#include "comp.h"
namespace math {
double getFirst(Comp a) {
return a.first;
}
...
}
Comp file: every function return Comp or double. I call function from cal.cpp file several times
cal.h
#include "comp.h"
#include "helper.h"
namespace math {
Comp calc(const string& str);
...
}
cal.cpp
#include "eval.h"
namespace math {
Comp calc(const string& str) {
...
}
}
Cal file: Some functions return with comp type, not just the cal function.
helper.h
namespace math {
...
}
helper.cpp
#include "helper.h"
namespace math {
...
}
helper file just contains few function that I calling from cal.cpp file. Each function is calling several times.
main.cpp
#include "calc.h"
int main() {
string str = " ";
pair<double,double> res = math::calc(str);
cout << res.first << " " << res.second << endl;
return 0;
}
In the whole project, I do not use any classes.
I included every file that I calling except the c++ original file.
I use the std namespace in each file but I do not write it here.
I absolutely no idea what could be the problem with my code.
If I also include cal.cpp in the main.cpp the code editor says undefined reference to each file that I calling from helper.h. I do not want to include cal.cpp in the main file I just mentioned it
You have to compile all your project's *.cpp files and then link them (results of compilation) properly - the linking process depends on the environment/IDE you're using, just look it up. If you're not linking it properly the final executable wont have all the functions definitions that requires, hence getting undefined reference.

std::ostream recognize without defining header

I created this code:
Main.cpp
#include <iostream>
#include "Quote.h"
int main()
{
derived().print(std::cout);
getchar();
return 0;
}
Quote.h
#pragma once
#include <string>
class base {
public:
std::string name() { return basename; }
virtual void print(std::ostream &os) { os << basename; }
private:
std::string basename = "abc";
};
class derived : public base {
public:
void print(std::ostream &os) { base::print(os); os << " " << i; }
private:
int i = 0;
};
If I don't include the iostream header file in Main.cpp, as expected, std::cout is not recognized. My question is: Why there's no problem with the use of std::ostream in Quote.h if iostream is not included?. Either cout as ostream are defined in the aforementioned library, why the cout use is a problem and ostream not?
I'm using VS 2017, in case this info is important.
All existing answers concentrate on #include <string>. I'd like to point at another side. Consider slightly modified version:
quote.h:
#pragma once
// uncomment to get an analog of original example
// #include <string>
struct Quote {};
std::ostream& operator<<(std::ostream& os, Quote const&)
{
return os << "quote\n";
}
main.cpp:
#include <iostream>
#include "quote.h"
int main()
{
std::cout << Quote{};
}
As you see #include <string> is commented out, quote.h still doesn't include iostream and the program still compiles. It does because only source files (.cpp, or translation units) are directly compiled. Headers are literally included. Now if we literally include quote.h in main.cpp we get:
#include <iostream>
// uncomment to get an analog of original example
// #include <string>
struct Quote {};
std::ostream& operator<<(std::ostream& os, Quote const&)
{
return os << "quote\n";
}
int main()
{
std::cout << Quote{};
}
(online)
It's what actually gets compiled. Notice everything is alright here, #include <iostream> before std::ostream usage.
And as was correctly pointed in comment to another answer, this is an example why it's important to always maintain self-sufficient headers that include all headers they depend on.
As #Evgeny pointed out in the comment, please check recommendations about organising our includes.
The header <string> declares an output operator using std::ostream. It seems the implementation you are using does so in a way making std::ostream generally available.
The C++ standard defines which headers make which declarations available at least. It doesn’t prohibit against additional names being made available. Different implementations may choose to not make the declarations available. I have tried making strictly only mandated declarations available in my implementation but this turns out to be not quite as simple as it sounds.
You include <string> in your header file. If you go to the string header you will see the first lines as (in VS2017):
// string standard header
#pragma once
#ifndef _STRING_
#define _STRING_
#ifndef RC_INVOKED
#include <istream> <----- here
#include <xstring_insert.h>
and going to the istream header:
// istream standard header
#pragma once
#ifndef _ISTREAM_
#define _ISTREAM_
#ifndef RC_INVOKED
#include <ostream> <-- here
which I think already answers your question. However, this is implementation dependent and you should not rely on this but include explicitly the iostream header.
The header <string> provides the extraction and insertion operators for std::string, so it has to make sure that std::ostream is at least forward-declared; your code only uses a reference to ostream, for which a forward declaration suffices, plus the aforementioned insertion operator, which is correctly declared.
So, strictly speaking, all that is needed by your header is already provided by the header <string>, although I'd probably explicitly include <iosfwd> for clarity.
Why there's no problem with the use of std::ostream in Quote.h if <iostream> is not included?
<iostream> get #included indirectly.
It's best not to rely on such indirection #includes. You can't count on it being true on all platforms. It may even change from debug build to release build.
When you want to use a class or a function, it's best to lookup the standard for the header that's supposed to provide the definition of the class and the declaration of the function, and #include the header directly in your file.

Trying to understand the keyword friend correctly via OOP in c++, coding issues

OK so here's my question, I'm trying to understand the use of friend in C++ with a working example on my PC for reference. I have everything set up in different classes, which are connected to one another with the .h files etc. (I think anyways). Can someone show me where I'm going wrong please? Cause i keep getting compiler errors and I don't understand what it means.
Yes I've researched the C:xxxx errors online, but I can't link the problem to the code I've got... It's obviously wrong! just need a push in the right direction / better understanding of C++... thank you!
//First class
#include <iostream>
#include <string>
using namespace std;
class Tutorial48
{
private:
int var;
int secret = 5;
public:
Tutorial48(int v);
friend class Tutorial48UseFriend;
void PrintVar();
};
// First class .cpp
#include "Tutorial48.h"
Tutorial48::Tutorial48(int v)
{
var = v;
}
void Tutorial48::PrintVar()
{
cout << var << endl;
cout << "Scret variable = " << secret << endl;
}
// Second class, whole point is to demo the friend keyword in C++!
#include "Tutorial48.h"
#include <iostream>
#include <string>
using namespace std;
class Tutorial48UseFriend
{
public:
Tutorial48UseFriend();
void showSecret(Tutorial48 tut48F)
{
// Just trying to increment by 1 so i know it's worked correctly.
tut48F.secret++;
cout << "My new private variabe = " << tut48F.secret << endl;
};
};
// Main function for outputting the whole thing.
#include "Tutorial48.h"
#include "Tutorial48UseFriend.h"
#include <string>
#include <iostream>
int main
{
Tutorial48UseFriend fr;
Tutorial48 t(24);
fr.showSecret(t);
getchar();
return 0;
}
Errors being produced....
Errors
Yeah so that's everything... As i said i'm new to this, so trying to understand it. Thank you to anyone for help in advance, cheers guys.
P.s. I do kind of understand the concepts of friend in c++ how it's used to access private variables of other classes etc. but i have no idea how to code it properly...
You should define the constructor of Tutorial48UseFriend like:
Tutorial48UseFriend(){}
and also pass Tutorial48 object by reference (by using '&'), and instead of making the function void make it return an int and then print it later, so:
int showSecret(Tutorial48& tut48F)
{
return ++tut48F.secret;
}

Declare a string type in a class (C++)

Here is my file.h :
#define MAXCOMPONENTS 20
#include <string>
#include <string.h>
#include <iostream>
class file{
public:
file(char const * filename);
virtual ~file();
void Takeinfocomponents();
void Takeshape();
void Getvalue(int i);
char *Getcomponents();
char *Getcolor();
protected:
private:
char const * filename;
String shape;
int value[MAXCOMPONENTS];
char components[MAXCOMPONENTS];
char color[MAXCOMPONENTS];
};
And my file.cpp :
#include <fstream>
#include <iostream>
#include <string.h>
#include <string>
#include "file.h"
using namespace std;
file::file(char const* filename)
{
cout << "constructor/fichier:" << filename << endl;
ifstream fichier(filename,ios::in);
if(fichier){
this->filename=filename;
fichier.close();
Takeshape();
Takeinfocomponents();
}else{
cout << "File name invalid." << endl;
}
}
file::~file()
{
}
char* file::Getcolor(){
return this->color;
}
char* file::Getcomponents(){
return this->components;
}
void file::Getvalue(int i){
cout << this->value[i] << endl;
}
void file::Takeinfocomponents(){ // pic up name of components, his number and his color
cout << "Takeinfocomponents/fichier:" << filename << endl;
ifstream fichier(this->filename,ios::in);
ifstream stop(this->filename,ios::in);
string line;
int i=0;
getline(fichier,line);
getline(stop,line);
getline(stop,line);
while(line!="/" && i!=99){ // take all informations while the stop signal isn't read
getline(stop,line);
fichier >> this->components[i] >> this->value[i] >> this->color[i];
cout << this->components[i] << this->value[i] << this->color[i] << endl;
i++;
}
fichier.close();
}
void file::Takeshape(){ // pic up the shape in .txt
cout << "Takeshape" << endl;
fstream fichier(this->filename,ios::in);
string shape;
fichier >> shape;
this->shape=shape;
fichier.close();
}
This is a part of a larger programm who make graphic from informations ( from the .txt ), this part is use to pic up informations from the .txt.
The problem come from the declaration of the :
String shape;
He told me that string is not a name type. I've tried with a small "s" :
string shape;
But this ain't working.
I've the impression that i miss a very small things that could unlock my problem.
Thx for help.
Notabene : I'm french and my english is not this good, please answer like i was a little child ahah !
You have to explicitly state the namespace:
std::string shape;
You shouldn't pollute the namespace in the headers, so using namespace std is not an option here.
See also the question about namespace pollution. If you just need strings, prefer to use
using std::string;
in the cpp file.
C++ uses the concept of a namespace. A namespace is used to group types, variables, etc. together in a meaningful way, regardless of the number of header files those types or variables are spread across.
In this example, the string type is inside the std namespace. std is short for Standard Template Library, and it is the namespace that most of C++'s library classes, etc. are stored in.
The correct way of accessing type inside a namespace is namespace::type, so the correct way of accessing the string type inside the std namespace is std::string. You can also write using namespace std to access the types in std without having to write std:: each time, but doing this in a global scope is a bad idea, because it pollutes the global namespace.
In the code you posted, string shape; appears before using namespace std, as the #include "file.h" appears before it. Therefore, it won't take effect.
To be able to use the string class and create string objects, you need to include...
#include <string>
... at the top of your header files.
You do not need...
#include <string.h>
The string class, like all STL classes, is part of the std namespace. If you do not want to write std:: before every class name, you can simply state...
using namespace std;
... at the top of your header files so that instead of...
std::string shape;
... you can simply use...
string shape;

C++ Namespace ofstream Won't Write

I'm working on making a game in C++. I have declared a Constant namespace used for global values that I need access to throughout the program. In there I have an ofstream for debugging purposes (yeah, I know it's not "constant" but it fits best there), which outputs only when it feels like it. I was able to make a small program demonstrating the problem. I apologize for it being spread across 4 files, but it is important, I promise.
main.cpp:
// Include necessary files
#include "test.h"
#include "constants.h"
#include <fstream>
using namespace std;
int main(int argc, char* argv[])
{
// Start of program
Constant::outstream.open("test.txt");
// ...
// Do stuff
// Output debugging info
Test test;
test.print("Test", Constant::outstream);
// ...
// Do other stuff
// End of program
Constant::outstream.close();
return 0;
}
constants.h:
#ifndef _CONSTANTS_H
#define _CONSTANTS_H
#include <fstream>
namespace Constant
{
static ofstream outstream;
}
#endif
test.h:
#ifndef _TEST_H
#define _TEST_H
#include <string>
#include <fstream>
#include "constants.h"
class Test
{
public:
void print(string str, ofstream& out);
};
#endif
test.cpp:
#include "test.h"
using namespace std;
void Test::print(string str, ofstream& out)
{
out << "out: " << str << endl << flush; // Works
Constant::outstream << "Constant::outstream: " << str << endl << flush; // Doesn't
}
In the test.cpp file, the out << ... line works as it should, while the Constant::outsream << ... line doesn't do anything even though I'm passing Constant::outstream as the out parameter! I don't see any reason why these two lines should be in any way different.
Before posting this, I tried putting test.cpp's code in test.h, just to have less files for the question, and was amazed to see it work. If I copy-paste the Test::print() function into test.h (whether inside or out of the class Test { ... }), then both output commands work correctly. the problem only occurs if Test::print()'s implementation is in a separate file.
It seems like any references to Constant::outstream simply don't work in class cpp files (no compile error, just nothing happens). It works in main.cpp and in class header files, but any class cpp file it seems not to. Unfortunately, this is a big program I'm writing so pretty much every class has its own cpp implementation file, and that's really the one place I need to use this ofstream. Does anyone know the reason for this?
Thanks in advance,
Doug
Constant::outstream has internal linkage, thus a separate instance is created for each translation unit. In short, Constant::outstream in test.cpp and main.cpp are two different variables.
§3.5.2 A name having namespace scope (3.3.6) has internal linkage if it is the name of
— a variable, function or function template that is explicitly declared static; or,
On the other hand, static class members would be visible throughout the program.
So, if you would write
struct Constant
{
static ofstream outstream;
}
instead of
namespace Constant
{
static ofstream outstream;
}
it would work.
However, note that the class must have external linkage; e.g. you should not put in in anonymous namespace.