I am really new in C++, and I can not solve the compilation error below.
data_structure.h
#include <stdint.h>
#include <list>
namespace A {
class B {
public:
bool func_init(); // init
};
};
data_structure.cpp
#include "data_structure.h"
using namespace A;
bool B::func_init(){
std::cout << "test init" << std::endl;
return true;
}
main.cpp
#include <iostream>
#include "data_structure.h"
using namespace A;
int main( int argc, char **argv ) {
A::B s;
s.func_init();
return 0;
}
I have an error as the following
undefined reference to `A::B::func_init()'
Please kindly advice why I can not get the func_init, eventhough it is declared as public? I have put also the correct namespace there.
Would appreciate for any response.
That's a linker error, so you're probably not compiling all your source files, or linking them together, or making some weird use of the C compiler (I see your files have the extension .c, some compilers treat them as C-source).
g++ main.cpp data_structure.cpp -o test should do it.
However I did need to add #include <iostream> to your data_structure.cpp file to resolve
data_structure.cpp: In member function ‘bool A::B::func_init()’:
data_structure.cpp:7:5: error: ‘cout’ is not a member of ‘std’
data_structure.cpp:7:33: error: ‘endl’ is not a member of ‘std’
and make it compile.
The definition of a function has to be in the namespace that declares the function. A using declaration just pulls in names from the namespace; it doesn't put you inside it. So you have to write data_structure.cpp like this:
#include "data_structure.h"
#include <iostream>
namespace A {
bool B::func_init() {
std::cout << "test init" << std::endl;
return true;
}
}
Or, if you prefer, you can use the namespace name explicitly in the function definition:
bool A::B::func_init() {
std::cout << "test init" << std::endl;
return true;
}
Have you tried not putting
using namespace A;
in your data_structure.cpp file and instead putting:
#include "data_structure.h"
bool A::B::func_init() {
std::cout << "test init" << std::endl;
return true;
}
I have the feeling that when you use using namespace A; doesn't let you append function definitions to the namespace, but only tells the compiler/linker where to look for Types or Functions...
Another theory:
Have you tried nesting your CPP code in the same namespace?
#include "data_structure.h"
namespace A {
bool B::func_init() {
std::cout << "test init" << std::endl;
return true;
}
}
Related
I created a new project in c++ but i keep getting the same error
Main.cpp
#include <iostream>
#include <string.h>
#include "Computer.cpp"
#include "Computer.h"
using namespace std;
int main()
{
cout << "Hello World!" << endl;
return 0;
}
Computer.h
#ifndef COMPUTER_H_INCLUDED
#define COMPUTER_H_INCLUDED
#include <string>
class Computer
{
public:
std::string marca;
float prezzo;
bool acceso;
Computer();
void Accenditi();
void Spegniti();
void ImpostaMarca(std::string m);
void ImpostaPrezzo(float p);
};
#endif
Computer.cpp
#include "Computer.h"
Computer::Computer()
{
}
void Computer::Accenditi()
{
if(!acceso)
{
acceso = true;
}
else
{
std::cout << "Sono già acceso";
}
}
void Computer::Spegniti()
{
if(acceso)
{
acceso = false;
}
else
{
std::cout << "Sono già spento";
}
}
void Computer::ImpostaMarca(std::string m)
{
marca = m;
}
void Computer::ImpostaPrezzo(float p)
{
prezzo = p;
}
The Problem
i don't understand what's wrong with Computer.cpp, i keep getting "cout is not a member of std". I tryed to add "using namespace std" and i also tryed to add the library #include but i get a new file called "makefile.win". How can i fix this error ?
You need to include iostream header in your Computer.cpp file as such:
include <iostream>
and to make your life easier, you can also add:
using std::cout;
using std::endl;
right at the bottom of your include, that way you don't have to keep adding "std::cout" everytime, you can just use "cout"
Also want to add:
You can remove the include computer.cpp from your main.cpp and just leave the header. The C++ linker will automatically link your computer.h and computer.cpp together since .cpp includes the header, and your main includes the computer.h
Add # include <iostream> at the files that you use std::cout and std::cin.
I wrote down an example code to try to replicate the error I am getting in a school project about the scope of an object:
In file: classTest.cpp
#include "headerone.h"
#include "headertwo.h"
#include <iostream>
using namespace std;
int main() {
ClassOne* pntrObj1 = new ClassOne;
ClassTwo* pntrObj2 = new ClassTwo;
pntrObj1->testClassOne();
return 0;
}
In file: headerone.h
#ifndef HEADERONE_H
#define HEADERONE_H
#include "headertwo.h"
#include <iostream>
using namespace std;
class ClassOne {
public:
void testClassOne() {
cout << "One Worked\n";
pntrObj2->testClassTwo();
}
};
#endif
In file: headertwo.h
#ifndef HEADERTWO_H
#define HEADERTWO_H
#include <iostream>
using namespace std;
class ClassTwo {
public:
void testClassTwo() {
cout << "Two Worked";
}
};
#endif
To be clear, the error is: pntrObj2 was not declared in this scope. The error comes from the file headerone.h
If I had to guess, I need to somehow pass the reference but I am not sure where to start for that. Any help is appreciated.
The variable pntrObj2 is only visible inside the scope in which it was declared, in this case your function main(). In other words, only code inside the curly braces of main() would be able to use the name pntrObj2 to reference that variable. However you can pass that value to other pieces of code by making it the argument of a function call.
So maybe what you want to do is add an argument to the testClassOne() method, so you can pass in the value of pntrObj2. So pntrObj1->testClassOne(); would become pntrObj1->testClassOne(pntrObj2);, and where you define testClassOne you can add a corresponding parameter. I'll let you figure this out so as to not completely do your homework for you :)
Here you include your file a lot of time and in testClassOne function, you do not declare pntrObj2
use
void testClassOne() {
cout << "One Worked\n";
ClassTwo* pntrObj2 = new ClassTwo()
pntrObj2->testClassTwo();
}
insteed of
void testClassOne() {
cout << "One Worked\n";
pntrObj2->testClassTwo();
}
I am trying to learn C++, however, the parameter to a method I have in my own class is misbehaving. When it uses a dataType of 'int', it works fine with no errors, but when I attempt to change it to a 'string' dataType, the program crashes with this error.
Error 1 error C2061: syntax error : identifier 'string' in temp.h ln
8 col 1
The classes I am using are as follows:
WORKING CODE
TesterClass.cpp // Entry Point
#include "stdafx.h"
#include "Temp.h"
int _tmain(int argc, _TCHAR* argv[])
{
Temp tmp;
tmp.doSomething(7);
return 0;
}
Temp.h
#pragma once
class Temp
{
public:
Temp();
void doSomething(int blah);
};
Temp.cpp
#include "stdafx.h"
#include "Temp.h"
#include <iostream>
#include <string>
using std::string;
Temp::Temp()
{
std::cout << "Entry" << std::endl;
string hi;
std::cin >> hi;
std::cout << hi << std::endl;
}
void Temp::doSomething(int blah)
{
std::cout << blah;
}
BROKEN CODE
Temp.h
#pragma once
class Temp
{
public:
Temp();
void doSomething(string blah);
};
Temp.cpp
#include "stdafx.h"
#include "Temp.h"
#include <iostream>
#include <string>
using std::string;
Temp::Temp()
{
std::cout << "Entry" << std::endl;
string hi;
std::cin >> hi;
std::cout << hi << std::endl;
}
void Temp::doSomething(string blah)
{
std::cout << blah;
}
When I adjust the parameter 'blah' to be a string, in both the .h and .cpp file, the problem occurs.
I have looked around, but none of the answers seem to solve my problem. I would greatly love help on this an I am out of ideas. I have tried reinstalling C++, messing with:
using namepace std;
using std::string;
std::string instead of string
etc.
If you know how to solve my problem I would love to hear from you. I am more than happy to provide more information.
C++ performs single-pass compilation, so std::string needs to be declared before you use it at all - including in the header file.
// Temp.h
#pragma once
#include <string>
class Temp
{
public:
Temp();
void doSomething(std::string blah);
};
I would encourage you to be specific in your header files when specifying classes like this, because you might easily come across another library that defines it's own string and then you would run into naming conflicts. Save the using import statements for your cpp files.
πάντα ῥεῖ had the write answer, thankyou!
They said to use std::string when needed, and to also #include <string> in the header file.
Please excuse me but I didn't know to give a name to the title in a short way.
Why do I need to declare an overloaded operator inside the header to make it work in this example:
HEAD.H
#pragma once
namespace test {
class A {
public:
A() : x(0) {}
int x;
};
A& operator++(A& obj); //this is my question
}
HEAD.CPP
#include "head.h"
namespace test {
A& operator++(A& obj) {
++obj.x;
return obj;
}
}
MAIN.CPP
#include <iostream>
#include "head.h"
using namespace std;
using namespace test;
int main() {
A object;
++object; //this won't work if we delete declaration in a header
return 0;
}
operator++ is defined and declared in a namespace inside "head.cpp" so why do I need to declare it one more time in a header?
Thank you.
The CPP files are compiled independently of each other, and they only see the header files they've included (which are in fact textually added to the source code of the CPP before compilation). As such you'll use the header file to inform the compiler that a function exists with that signature (be it an operator overload).
Then the output from your CPP files is put together by the linker, which is when you'd find out if for instance you had declared a function in a header file but never taken the trouble to implement it.
Simple example with namespaces:
#include <iostream>
namespace test{
int f() { return 42; }
int g() { return -1; }
}
namespace other{
int f() { return 1024; }
}
using namespace other;
int main(){
//error: 'g' was not declared in this scope
//std::cout << g() << std::endl;
std::cout << test::f() << std::endl; //42
std::cout << f() << std::endl; //1024
return 0;
}
if I define a namespace log somewhere and make it accessible in the global scope, this will clash with double log(double) from the standard cmath header. Actually, most compilers seem to go along with it -- most versions of SunCC, MSVC, GCC -- but GCC 4.1.2 doesn't.
Unfortunately, there seems no way to resolve the ambiguity, as using declarations are not legal for namespace identifiers. Do you know any way I could write log::Log in the global namespace even if cmath is included?
Thanks.
EDIT: Would anybody know what the C++03 standard has to say about this? I would have thought that the scope operator sufficiently disambiguates the use of log in the code example below.
#include <cmath>
namespace foo
{
namespace log
{
struct Log { };
} // namespace log
} // namespace foo
using namespace foo;
int main()
{
log::Log x;
return 0;
}
// g++ (GCC) 4.1.2 20070115 (SUSE Linux)
// log.cpp: In function `int main()':
// log.cpp:20: error: reference to `log' is ambiguous
// /usr/include/bits/mathcalls.h:110: error: candidates are: double log(double)
// log.cpp:7: error: namespace foo::log { }
// log.cpp:20: error: expected `;' before `x'
I'd suggest:
foo::log::Log x; // Your logging class
::log(0.0); // Log function
Generally I wouldn't write using namespace foo; as there is no point having it in the foo namespace if you're not going to use it and it pollutes the global namespace.
See this related question:
How do you properly use namespaces in C++?
Although it does not help you, the error from GCC 4.1.2 is incorrect. The log in log::Log can only refer to a class or namespace name.
If your code also needs to compile with GCC 4.1.2, then there are two options:
Use the fully qualified name foo::log::Log
Use a namespace alias:
namespace log1 = foo::log;
log1::Log logger;
cmath uses ::log for some reason to get it from the global scope and can't decide between the function and your namespace.
Namespaces keep code contained to prevent confusion and pollution of function signatures.
Here's a complete and documented demo of proper namespace usage:
#include <iostream>
#include <cmath> // Uses ::log, which would be the log() here if it were not in a namespace, see https://stackoverflow.com/questions/11892976/why-is-my-log-in-the-std-namespace
// Silently overrides std::log
//double log(double d) { return 420; }
namespace uniquename {
using namespace std; // So we don't have to waste space on std:: when not needed.
double log(double d) {
return 42;
}
int main() {
cout << "Our log: " << log(4.2) << endl;
cout << "Standard log: " << std::log(4.2);
return 0;
}
}
// Global wrapper for our contained code.
int main() {
return uniquename::main();
}
Output:
Our log: 42
Standard log: 1.43508
In c++0x or c++11, the following should work, compile with -std=c++0x or -std=c++11:
#include <iostream>
#include <math.h>
namespace ___ {
namespace log {
void init() {
std::cout << "log::init()" << std::endl;
}
} // namespace log
} // namespace ___
using namespace ___;
int main() {
log::init();
std::cout << ::log(3.2) << std::endl;
return 0;
}