This is a noob question, sorry, I'm coming from Java and have no idea why my OO stuff isn't working. I have this main:
#include <iostream>
#include "Foo.h" //changed name
using namespace std;
int main(int argc, char*argv[])
{
int choice;
cin >> choice;
Foo net;
switch(choice)
{
case 1: net.buildNetwork(); break;
}
}
This Foo.h file:
#ifndef FOO_H
#define FOO_H
#include <iostream>
struct City{
std::string cityName;
std::string message;
City *next;
City(){}; // default constructor
City(std::string initName, City *initNext, std::string initMessage)
{
cityName = initName;
next = initNext;
message = initMessage;
}
};
class Foo
{
public:
Foo();
~Foo();
void addCity(std::string, std::string);
void buildNetwork();
void transmitMsg(char *); //this is like a string
void printNetwork();
protected:
private:
City *head;
City *tail;
};
#endif // FOO_H
And this Foo.cpp file, all in the same directory:
#include "Foo.h"
#include <iostream>
using namespace std;
Foo::Foo()
{
head = tail = NULL;
}
Foo::~Foo(){}
void Foo::buildNetwork()
{
cout << "works" << endl;
}
void Foo::transmitMsg(){}
void Foo::printNetwork(){}
void Foo::addCity(){}
When I compile, I get
/tmp/ccNx3fY5.o: In function `main':
main.cpp:(.text+0x38): undefined reference to `Foo::Foo()'
main.cpp:(.text+0x4c): undefined reference to `Foo::buildNetwork()'
main.cpp:(.text+0x59): undefined reference to `Foo::~Foo()'
main.cpp:(.text+0x7e): undefined reference to `Foo::~Foo()'
collect2: error: ld returned 1 exit status
What's wrong? Also, another question: in Foo.cpp, why do I need Foo::Foo() etc? I used namespace std, so why can't I just say Foo()?
Looking at the way you compile, you are only providing only one source file (main.cpp) whereas the correct way is to specify all the source files. In your case, it would be:
g++ main.cpp foo.cpp -o executable
The "undefined reference" error is a error thrown at the linking stage when the linker can't resolve the names correctly because, you didn't link the source files properly like above.
Additionally, make sure that when you declare a function prototype, the implementation of the function should also have the same signature. In your example, you provided the function prototypes as:
void transmitMsg(char *);
void addCity(std::string, std::string);
But your implementation of those functions don't have the correct signature. They should have been:
void Foo::transmitMsg(char *){}
void Foo::addCity(std::string, std::string){}
why do I need Foo::Foo() etc?
Because Foo() is a function of the class Foo.
I used namespace std, so why can't I just say Foo()?
When you make a call to using namespace ; all symbols in that namespace will become visible without adding the namespace prefix. A symbol may be for instance a function, class or a variable.
Foo is not a namespace like "std". It is a user-defined class.
Also, another question: in Foo.cpp, why do I need Foo::Foo() etc? I
used namespace std, so why can't I just say Foo()?
You need to write Foo::Foo() in foo.cpp because you are defining the constructor outside the body of the Foo class which is present in foo.h.
std is the standard namespace and using that in no way absolves you from referring to the Foo class you have created since its not a part of the standard namespace
You have not included foo.cpp in your compile command, So this is why you cant link the functions. You need to use the command line argument:
g++ main.cpp foo.cpp -o main
This allows the compiler to find the functions in foo.cpp.
Related
I'm having one of those "undefined reference to " errors when compiling a c++ program. I know this is common pitfall, but so far was unable to figure out what I'm doing wrong.
Here's the relevant code. Ex1Two_Sum.h:
#ifndef EX1TWO_SUM_H
#define EX1TWO_SUM_H
#include <vector>
using namespace std;
namespace ddc {
class Ex1Two_Sum
{
public:
void f();
protected:
private:
};
}
#endif
Ex1Two_Sum.cpp:
#include <vector>
#include <cstddef>
#include <iostream>
using namespace std;
namespace ddc {
class Ex1Two_Sum {
public:
void f(){
cout << "works" << endl;
}
};
}
And finally, main.cpp:
#include <iostream>
#include "Ex1Two_Sum.h"
using namespace std;
using namespace ddc;
int main()
{
Ex1Two_Sum ex1;
ex1.f();
return 0;
}
I compile as follows:
g++ -std=c++11 -c Ex1Two_Sum.cpp
g++ -std=c++11 -c main.cpp
g++ Ex1Two_Sum.o main.o
yielding the following message:
main.o: In function `main':
main.cpp:(.text+0x2c): undefined reference to `ddc::Ex1Two_Sum::f()'
collect2: error: ld returned 1 exit status
Your source file redefines the whole class, with an inline function definition, when it just needs to provide a non-inline function definition.
#include "Ex1Two_Sum.h"
void ddc::Ex1Two_Sum::f() {
std::cout << "should work\n";
}
Also, please don't put using namespace std; in a header. Not everyone wants the global namespace polluted in potentially surprising ways.
First, which line of the command throws that error?
Second, I think you forgot to include the Ex1Two_Sum.h in the Ex1Two_Sum.cpp
Third you need to change class ....... in Ex1Two_Sum.cpp to:
void Ex1Two_Sum::f(){...}
I want to modify object "t1" of the class "abc" in "update" function which is defined in different file(temp2.cpp) than where "t1" is defined(temp1.cpp). I tried to use extern but that resulted in error. Please suggest nice way of doing this.
temp1.ccp
#include<iostream>
#include "test2.cpp"
using namespace std;
class abc{
public:
int x;
char y;
void printxy(){
cout<<x<<y<<endl;
}
};
abc t1;
int main(){
update();
return 0;
}
test2.cpp
extern abc t1;
void update(){
t1.x=5;
t1.y='A';
t1.printxy();
};
In file included from test.cpp:2:0: test2.cpp:1:8: error: `abc' does not name a type
extern abc t1;
^
test2.cpp: In function `void update()':
test2.cpp:3:2: error: `t1' was not declared in this scope t1.x=5;
You include test2.cpp before the declaration of class abc: the included file just gets expanded at the location where the #include occurs. You might want to use your code with the compiler's -E option to see how the file looks after preprocessing (in which case you probably also want to omit the #include <iostream> as it will produce lots of output).
In general, it isn't a good idea to include .cpp files. Did you mean the declarations to be a header file (e.g., test2.h) and include that at the type of test2.cpp? In that case the order of the declaration would be OK.
Finally I got it. Thanks for your comments :)
class.h
class abc{
public:
int x;
char y;
void printxy(){
std::cout<< x << y <<std::endl;
};
};
func.h
extern abc t1;
void update(){
t1.x=5;
t1.y='A';
t1.printxy();
};
main file
#include <iostream>
#include "class.h"
#include "func.h"
abc t1;
int main(){
update();
return 0;
}
Output
5A
I'm trying to intercept "the data" from standard output (for this question I'm working with cout). Also for this question I'm working with double, but the program should be able to handle any primitive data type. When I try to compile my code I get this error:
undefined reference to `std::ostream& SpyOutput::operator<<
(double const&)' collect2: error: ld returned 1 exit status
this is my main:
#include "SpyOutput.h"
#define endl '\n'
int main ( int argc, char *argv[], char *env[] ) {
double d1 = 12.3;
SpyOutput spy(&cout);
spy << d1;
return 0;
}
this is my header file:
#include <iostream>
using namespace std;
class SpyOutput {
private:
ostream* output;
public:
SpyOutput(ostream* os);
template <class T>
ostream &operator<<(const T &x);
};
this is my implementation file:
#include "SpyOutput.h"
SpyOutput::SpyOutput(ostream* os){
output = os;
}
template <class T>
ostream& SpyOutput::operator<<(const T &x){
// SOME CODE GO HERE
return *output;
}
I have googled this error (and similar) without finding a working solution, thanks in advance for any help or hint that you can provide to me! :-)
What's the problem?
For an explanation why it doesn't compile, see "Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?"
As an example, consider the header file foo.h which contains the following template function declaration:
// File "foo.h"
template<typename T>
void foo();
Now suppose file foo.cpp actually defines that template function:
// File "foo.cpp"
#include <iostream>
#include "foo.h"
template<typename T>
void foo()
{
std::cout << "Here I am!\n";
}
Suppose file main.cpp uses this template function by calling foo():
// File "main.cpp"
#include "foo.h"
int main() { foo<int>(); ... }
If you compile and link these two .cpp files, most compilers will generate linker errors. Because in order for the compiler to generate the code, it must see both the template definition (not just declaration) and the specific types/whatever used to "fill in" the template. If the template body is defined in the .cpp the compiler won't see it and hence won't generate any code for it.
How to fix it?
There is more than one possible solution around this issue. I suggest moving the definition of the template function into the .h file.
// File "foo.h"
template<typename T>
void foo()
{
std::cout << "Here I am!\n";
}
In your source you can call it as usual:
// File "main.cpp"
#include "foo.h"
int main() { foo<int>(); ... }
You need to place your template implementation of SpyOutput::operator<< into the header file
I'm new to C++ and need some help with namespaces.
Following are my 4 files:
node.h <--class interface
node.cpp <--implementation
testNodeFunctions.cpp
testNodeMain.cpp
//node.h
---------------------------------
#include <iostream>
using namespace std;
namespace namespaceName{
class Node {
private:
int data;
public:
void setData( int x);
int getData();
};
//and some more functions
}
//node.cpp
-------------------------------------
#include <iostream>
#include "node.h"
using namespace std;
namespace namespaceName {
//provides implementation of the memeber functions
int Node::getData() const{
return data;
}
void Node::setData(int x){
data=x;
}
}//namespace
//testNodeFunctions.cpp
-------------------------------------
#include <iostream>
#include "Node.h"
using namespace std;
using namespace namespaceName;
void showData(){
//creates a Node object and prints some stuff
Node a=37;
cout<<a.getValue()<<endl;
}
//testNodeMain.cpp
----------------------------------------------
#include <iostream>
#include "Node.h"
void showData();
int main(){
//calls methods from testNodeFunctions
showData();
}
I'm not sure if I'm defining the namespace currently.
How Do I call the showData() function from the testNodeMain.cpp file. Currently I'm getting linker error stating that "undefined reference to namespaceName::Node::methodname"
Thanks so much in advance
Okay. That make sense. I removed , using namespace std from header. I'm compiling the testNodeMain.cpp which has the main(). the TestNodeMain.cpp calls functions from testNodeFunctions.cpp. testNodeFunctions.cpp creates Node object.
In your header file node.h, you have
void setData( int x);
int getData();
where as in your node.cpp file, you have:
int Node::getValue() const{
return data;
}
void Node::setValue(int x){
data=x;
}
You need to change your Node::getValue() const {} to Node::getData() const {}, or change the names of the functions in your header files to int getValue() and void setValue (int x)
The function names in the header files for the class and the actual .cpp file should be the same.
It's really hard to tell without a complete compiling example that induces your problem, but it looks like you forgot to include node.cpp on your link line.
I'm not sure if I'm defining the namespace currently.
That looks fine, although without seeing what you've put inside it I can't say for sure.
How Do I call the showData() function from the testNodeMain.cpp file?
The function needs to be declared before you can call it. Add the following declaration, either after the #include lines in testNodeMain.cpp, or in another header file which must then be included from testNodeMain.cpp:
void showData();
Then you can call the function from main:
int main() {
showData();
}
Currently I'm getting linker error stating that "undefined reference to namespaceName::Node::methodname"
You need to make sure you're compiling and linking all the source files, not just the main one. If you're using GCC, the build command should look something like:
gcc -o testNode testNodeMain.cpp testNodeFunctions.cpp node.cpp
If you're still getting the error in that case, then check that you have actually implemented the methods. If you think you have, then please update the code in your question to include the implementation of one of the missing methods so we can check that for you.
I'm not too familiar with c++ and how instantiating objects work, so this is probably a very simple thing to solve. When I compile with g++ I get the error " undefined reference to 'Foo::Foo(std::string)' ". I want to create an instance of the class Foo that has a string parameter in its constructor. Here is the code:
Foo.h
#include <string>
using namespace std;
class Foo
{
public:
Foo(string s);
private:
string id;
};
Foo.cpp
#include <string>
#include "Foo.h"
using namespace std;
Foo::Foo(string s)
{
id = s;
}
main.cpp
#include <string>
#include "Foo.h"
using namespace std;
int main()
{
Foo foo("bar");
return 0;
}
You're probably not including Foo.cpp in your compile line. It should look something like this:
g++ main.cpp Foo.cpp -o testFoo
Not related to the problem you were having but consider making a couple minor changes:
Pass the argument in a const reference. const because you do not plan on changing the value of the argument and reference so that you do not create any additional temporary objects.
C++ has an initializer concept that is more efficient then using the assignment operator on member 'id' in the body of the constructor. The current version of the constructor will call member id's default constructor and then its assignment constructor. The initializer concept (i.e. 'id(s)') will just call one method the copy constructor.
Foo::Foo(const string& s) : id(s)
{
}