Instantiating & using c++ class using header & implementation files [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I'm basically trying to instantiate an object from a class in c++ and use one of the member functions. This feels like a pretty standard problem, but all of the solutions I find online are either simple bracket issues, or scope resolution stuff that seems really obvious, or massively complex examples that shroud what's actually going on in over-complexity. I really appreciate anyone that Might be able to help me understand what I'm doing wrong with these files.
The errors I get are
undefined reference to Test::Test()'
undefined reference to Test::msg()'
I have three files, a main, a Test.hpp, and Test.cpp.
main.cpp
#include "Test.hpp"
#include <iostream>
using namespace std;
int main(){
Test var;
var.msg();
return 0;
}
Test.hpp
#ifndef TEST_HPP
#define TEST_HPP
class Test{
public:
Test();
void msg();
};
#endif
Test.cpp
#include "Test.hpp"
#include <iostream>
using namespace std;
Test::Test(){
cout << "instantiated\n\n";
}
void Test::msg(){
cout << "Hello\n\n";
}

Considering you use codeblocks as your IDE just go to: project settings -> project build options -> search directories -> add and locate where your .cpp and .h files are. Then it will ask you if you want to keep this as relative path. Say no.
If you using some other ide its almost the same proccess, just comment me and i will provide you the steps.
Btw there is no need to include iostream in main since you have already included it in test.

Related

C++ - Undefined reference to octomap::OcTree::OcTree(double)' [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 months ago.
I'm trying to use the library octomap and have installed according to the instructions in their GitHub. However, when I try to build and run this simple code with VSCode build task (with g++) I get the error: undefined reference to `octomap::OcTree::OcTree(double)' and other undefined references to Octomap related code. VSCode recognizes that the library is installed (it suggests it when I type #include <...> ) and gives me more information about the octomap functions when I hover over them.
#include <iostream>
#include <octomap/octomap.h>
#include <octomap/OcTree.h>
using namespace std;
int main()
{
octomap::OcTree tree(0.1);
cout << "Hello, World!! \n";
return 0;
}
Octomap header files are in /usr/local/lib/octomap/octomap/include/octomap from what I can tell. I haven't coded with C++ a lot, so this might be just a newbie mistake that I'm missing. I've tried several approaches but still can't get it to work. What am I missing here?
Thanks in advance.
your problem is the program wasn't linked with octomap library
use cmake and include some lines like:
find_package(octomap REQUIRED)
include_directories(${OCTOMAP_INCLUDE_DIRS})
target_link_libraries(${OCTOMAP_LIBRARIES})
or from command line with g++ <source files> -loctomap -loctomath
refer : http://wiki.ros.org/octomap

Use clang preprocessor to concatenate C++ source files into one [duplicate]

This question already has answers here:
Merge C++ files into a single source file
(8 answers)
Closed 2 years ago.
In the context of a coding contest, I must copy/paste all my C++ code in a single html input form, the code being compiled remotely. With the code getting bigger, I'd like to split the code into several files.
So, I have several C++ source files, one is main.cc and some others headers such as f.h.
I'd like these source files to be concatenated in a single source file allinone.cc with so that i can compile with clang++ allinone.cc.
I guess this can be achieved using clang preprocessor.
A minimal example would be:
main.cc
#include <iostream>
using namespace std;
#include "f.h"
int main() {
f();
}
f.h
#pragma once
#include <iostream>
using namespacestd;
void f() {
cout <<
}
The closest I could get is with :
clang -E -nostdinc main.cc | grep -v "^#" > allinone.cc
which produces:
#include <iostream>
^~~~~~~~~~
1 error generated.
using namespace std;
using namespacestd;
void f() {
cout <<
}
int main() {
f();
}
The -nostdinc option successfully avoids including code from standard includes. However, the original #include <iostream> disappears and the namespace specification is repeated.
Is there a way to invoke clang preprocessor to achieve the concatenation described in a straight forward manner?
clang -nostdincdoes another thing, not what you expect. This key disables the standard include directories from the include search paths. So, you get the error since the preprocessor is unable to include the file -nostdinc, could not find it in the known include search paths.
What you want is impossible to achieve. You should use cat your files and clean the result manually or use a special software that can remove #include. I suggest you just use a combinations of grep, sort, uniq and place removed and filtered #include into the top of the concatenated file.

Referring to an object from custom library gives error: "pointer to incomplete class type is not allowed"

So in my Visual Studio solution I'm making a library and I have two Visual Studio projects, one for the library and one for the sandbox. In the library I'm trying to use forward declarations to create a class. What I'm simply doing in this example is creating a header file for my class, declaring std::string with the following forward declaration and creating a member pointer with that class.
Library project:
ClassFromLibrary.h
#pragma once
namespace std {
class string;
}
class ClassFromLibrary {
public:
ClassFromLibrary();
~ClassFromLibrary();
std::string* forwardDeclaredString;
};
ClassFromLibrary.cpp
#include "ClassFromLibrary.h"
#include <string>
ClassFromLibrary::ClassFromLibrary()
: forwardDeclaredString(new std::string("Hello, world!"))
{
}
ClassFromLibrary::~ClassFromLibrary()
{
}
Sandbox project
main.cpp
#include <Library/ClassFromLibrary.h>
#include <iostream>
int main()
{
ClassFromLibrary test;
std::cout <<
*test.forwardDeclaredString //Root of the problem
<< std::endl;
std::cin.get();
}
The problem
As I said earlier, the library project compiles perfectly. However, the error which I mentioned in the title shows up when the forward declared member variable is referenced in any file from the sandbox project. I have a larger project where I get the same error, and the reason I want to achieve this is because I am using other external libraries within my library project, and when I create applications with it I don't want to have to put all the library include directories in the project properties, only the one for my library.
Thanks in advance!
You know that putting names in namespace std makes program ill-formed (except for some cases?)? Well, know you know why. The bug you have is a symptom of undefined behavior.
In my test, the way you declared your forward declaration in std is not how it is actually declared in string header. Yet it's a same name, so now you have name conflict (you have it as soon as you include iostream, which includes string. This is what my compiler is telling me when I am try compile your code:
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/basic_string.h:6628:17:
error: reference to 'string' is ambiguous
struct hash<string>
This is different from the error you put in the question, but since the behavior is undefined, anything can happen.

simple C++ code linker error [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
Im trying to run a very simple snippet of code. I've been getting a linker error. My code looks like this:
main.cpp -->
#include <iostream>
#include "Complex.h"
using namespace std;
int main()
{
Complex c1(1.0, 5.0); // this should create Complex object 1.0 + i5.0
return 0;
}
Complex.h -->
#include <iostream>
class Complex {
private:
double real;
double imaginary;
public:
Complex(double, double);
void setReal(double);
void setImaginary(double);
};
Complex.cpp -->
#include "Complex.h"
#include <cmath>
Complex::Complex(double x, double y) {
setReal(x);
setImaginary(y);
}
void Complex::setReal(double x) {
real = x;
}
void Complex::setImaginary(double x) {
imaginary = x;
}
The error I've been getting looks like this:
I have been trying to run my main for a while but I keep getting the linker error. I have no clue what's causing it. I would appreciate any suggestions.
Just do
g++ main-3.cpp complex.cpp
mind the filename main-3, this is inconsistent in your question.
You have to feed all cpp files you are using into the g++ commandline to tell g++ where the code for the functions defined in the header lies. Read up on .o files, static linking and understand what that means.
Here is a little guide I follow to understand file inclusion and other factors:
c++ compilation is moronically simple:
read .cpp file
replace every #include statement with the text of the specified file (just dump it in)
If the resulting text still has #include directives (now from the header files), goto step 2.
Compile the hughe messy blob into a ´.o´ object file, replace calls to functions with symbols and add to that file a table of known symbols and where they are defined.
if there are more .cpp files specified, start a new empty text blob. Goto step 1.
call the linker ´ld´ to link all object files together, replace symbols with the actual addresses.
Strictly speaking, above is a little bit of a lie nowadays and a lot is left out and no optimizations mentioned. But it is still a useful guide to the compiler's behaviour.
To use it to interpret your error:
Complex.h got dumped into your blob, via the #include in main.cpp , but Complex.cpp did not. g++ generated an internal temporary .o file for you that contained something along the lines of
PUT 1.0 on Stack
PUT 5.0 on Stack
JUMP Complex::Complex
... and ran the linker ´ld´ with that .o file.
ld Could not find the address of the symbol Complex::Complex,
it needs a memory address to jump to.
If you compile Complex.cpp as well, the resulting Complex.o will have a symbol table with, for example, this entry:
Complex::Complex = 0xaaff
The linker, given Complex.o can now replace the symbol in main.o with an address.
PUT 1.0 on Stack
PUT 5.0 on Stack
JUMP 0xaaff

iostream.h: no such file or directory [duplicate]

This question already has answers here:
fatal error: iostream.h no such file or directory [duplicate]
(3 answers)
Closed 6 years ago.
I am using Windows 8.1 and Dev C++ and I have the following code:
#include<iostream.h>
main()
{
cout<<"welcome to devc++";
system("pause");
}
The syntax is correct, but I get an error that says:
[Error] iostream.h: No such file or directory
I have tried to change to location of this .cpp folder, watched video tutorials, but I could not point out why I am getting this error and how to remove it.
You need to use #include<iostream> instead of #include<iostream.h>. The later one has been deprecated now; which is why you face the error. More details here.
Besides, main() being a function, should have a return type. So, you should write int main() and not just main().
Just do,
#include <iostream>
instead of
#include <iostream.h>
because, as C++ progressed from specific implementation to standard one,.h were deprecated from he library.
In addition to changing to
#include <iostream>
You can also add
using namespace std;
before main if you want to use cout without having to use std::cout.