I am trying to call another function, foo(), in the Raw class from main.cpp but I keep on getting this error and I do not understand what is wrong with my code. I am working in C++, and I am using the QT framework. I am new to this language and framework.
Error:
LNK2019: unresolved external symbol "public:void __thiscall RAW::foo(void)" (?foo#Raw##QAEXXZ) referenced in function_main. File not found:main.obj
main.cpp
#include "raw.h"
using namespace std;
int main(int, char*)
{
Raw newRaw;
newRaw.foo();
return 0;
}
raw.cpp
#include "raw.h"
#include <iostream>
using namespace std;
void foo()
{
cout << "hi\n";
}
Raw::Raw()
{
cout << "raw\n";
}
raw.h
#ifndef RAW_H
#define RAW_H
class Raw
{
public:
Raw();
void foo();
};
#endif // RAW_H
In raw.cpp you have to define foo like this:
void Raw::foo()
{
cout << "hi\n";
}
You have to put Raw:: so that the compiler knows that this is the class member function foo and not some other independent function.
As Mihai was saying, you can also define it in the Header file (.h/.hpp), but that is considered bad practice if your class method is complex in any way.
class Raw {
public:
void foo() {
cout << "hi\n";
}
};
Only time you should really ever do this is for extremely simple classes and for methods that are nothing more than getters really.
You should understand the difference between defining and declaring something in C++.
Declaring is to simply make a prototype, for example void doSomething(int); is a valid declaration as it says that the method doSomething takes an int and returns void.
Now, you need to describe what it does. This is the definition when you do void doSomething(int val) { cout << val << endl; } as you are now describing what to do with that function.
You can make the definition in the header file, as I showed, or in the source file (.c/.cpp) as Mihai showed (which is best practice). You can only make your declarations in the Header file, though.
Ok, this are some alternatives:
//raw.h
#ifndef RAW_H
#define RAW_H
class Raw
{
public:
Raw();
void foo(){cout << "raw\n";}
};
or
//raw.h
#ifndef RAW_H
#define RAW_H
class Raw
{
public:
Raw();
void foo();
};
Raw::Raw()
{
cout << "raw\n";
}
In both cases you won't need the implementation in raw.cpp anymore. But as I said before, my first solution is standard c++ practice.
Related
Let's say that we have a class definition and implementation:
//foo.h
#ifndef FOO_H
#define FOO_H
class Foo {
public:
void print();
};
#endif
//foo.cpp
#include "foo.h"
#include <iostream>
void Foo::print() {
std::cout << "Hello world!" << std::endl;
}
And let's say that those are part of the source code of another project, then I want to override the Foo::print behaviour without modifying the original source code, in another .cpp file:
//mylib/foo.cpp
#include "../foo.h"
#include <iostream>
void Foo::print() {
std::cout << "Method overrided!" << std::endl;
}
This isn't the regular override pattern (which exists on inherited classes that overrides virtual functions), this would be like a new implementation of the already implemented method.
I don't know if such concept exists in C++, but if it exists, what would be the correct syntax?
If the class resides in a shared library, you can use LD_PRELOAD to replace individual functions with new definitions. Described for example here: https://axcheron.github.io/playing-with-ld_preload/
I am trying to load a class defined in a .dll file. However there are two slightly different ways of defining the class in the dll. I'm not sure which is the more legit way to do it, and I don't know why the second way also works. Here is a simple example:
Method 1:
In main.cpp:
#include <iostream>
#include <windows.h>
#include <memory>
#include "bar.h"
using namespace std;
typedef bar* (* MYDLLPROC)();
int main()
{
unique_ptr<bar> theresult;
auto thelib = LoadLibrary(TEXT("foo.dll"));
if (thelib != NULL) {
MYDLLPROC theprocs = (MYDLLPROC)GetProcAddress(thelib, "Myfoo");
cout << "load successfully" << endl;
theresult.reset(theprocs());
theresult->printmsg();
} else {
cout << "cannot load the dll" << endl;
}
return 1;
}
The bar is defined as a pure virtual class in bar.h:
class bar {
public:
virtual ~bar() {};
virtual void printmsg() = 0;
};
In the foo.dll source file:
#include <iostream>
#include <windows.h>
#include "bar.h"
using namespace std;
class foo: public bar {
public:
foo() { cout << "foo is instantiated" << endl; }
~foo() {}
void printmsg() final { cout << "msg from foo print" << endl; }
};
extern "C" __declspec(dllexport) foo* __cdecl Myfoo()
{
return new foo();
}
In the first method the pure virtual class bar is used as an interface, and it makes sense that its member function(s) is overridden by that in foo when the dll is loaded.
However, I found that foo doesn't have to be derived from bar, everything still works as long as foo has a Vtable:
In the second method, everything is the same except for the definition of foo:
#include <iostream>
#include <windows.h>
using namespace std;
class foo {
public:
foo() { cout << "foo is instantiated" << endl; }
virtual ~foo() {}
virtual void printmsg() final { cout << "msg from foo print" << endl; }
};
extern "C" __declspec(dllexport) foo* __cdecl Myfoo()
{
return new foo();
}
Could anyone please let me know why the second method works? I'm a bit confused because foo and bar are not related but the member function in bar can still be overridden.
So you cast a function returning foo* as a function returning bar* and then invoking it.
The end result is that you have a pointer to foo which is a pointer to an unrelated type bar. Using it in any way will lead to undefined behavior.
It appears to work in this specific case because the position of the printmsg virtual function in both vtables is the same, so invoking bar::printmsg on an instance of foo simply calls the "Nth entry in the vtable". If you add another virtual member to foo before printmsg, then it might get called instead (or the program might crash).
First example is very fragile because it implicitly relies on foo and bar being pointer-interchangeble.
Second example is broken because function Myfoo returns a pointer to class foo that is not related to bar and dereferencing it causes undefined behavior.
Function signature must match the function implemented in the dll. What you have right now is basically a wild reinterpret_cast from foo * to bar *.
Ive been using c++ for some months now but Ive come across an error when I use header and source code files. I create a source code file
that contains a class gun(example not actual program):
class gun
{
private:
int stuff;
public:
void doStuff();
};
void Gun::doStuff()
{
cout << stuff << endl;
}
and then i created a header file and declared the class like this:
class gun;
then in my main source file i do this:
int main()
{
gun *mygun = new gun;
mygun->doStuff();
return 0;
}
however when i try to execute it i get the error:
invalid use of incomplete type 'class gun' and i think the problem is how i declared it in the header, did i do it wrong? how was i meant to do it? thanks.
Thanks Everyone that helped! I understand now, i thought that only the forward declaration
went into the header file, thanks for all your answers!
You seem to be going about seperating the implementation and header file the wrong way. Forward declarations should not go in the header file. The entire declaration should! This is how your code should be structured
Gun.hpp
#pragma once
class Gun
{
private:
int stuff;
public:
void doStuff();
};
Gun.cpp
#include "Gun.hpp"
#include <iostream>
using std::cout;
using std::endl;
void Gun::doStuff()
{
cout << stuff << endl;
}
main.cpp
int main()
{
Gun *mygun = new Gun;
mygun->doStuff();
delete mygun; // <-- remember this!
return 0;
}
the separation of header and implementation is crucial in C++ and other languages! You should only declare the class in the header along with its full interface (as above) and include all implementation details in the .cpp file (as above :)
The entire declaration of the gun class needs to be in the header file. What you declared in the header file is a forward declaration, which is not enough by itself to create an instance of the class. Forward declarations are useful for allowing other code to declare pointers only, since the compiler does not need to know the full details just to declare a pointer. But a forward declaration can't be used for creating actual object instances of the class. That is why you are getting errors about an incomplete type. From main()'s perspective, it has no idea what gun actually looks like, so it can't create a full instance of it.
The implementation of the methods for the gun class needs to be in the gun's source file, which can #include the header file to validate and access the class members.
gun.h
#ifndef gun_h
#define gun_h
class gun
{
private:
int stuff;
public:
void doStuff();
};
#endif
gun.cpp
#include "gun.h"
#include <iostream>
void gun::doStuff()
{
std::cout << stuff << std::endl;
}
Now, in main() (or any other source file), you can #include the header file and use the class as needed:
#include "gun.h"
int main()
{
gun *mygun = new gun;
mygun->doStuff();
delete mygun;
return 0;
}
In gun.h
#ifndef GUN_H_
#define GUN_H_
// You can use #pragma once too here
class gun
{
private:
int stuff;
public:
void doStuff();
};
#endif
In gun.cpp file
#include "gun.h"
void gun::doStuff()
{
cout << stuff << endl;
}
and then main.cpp
#include "gun.h"
int main() {
//your code using the class
gun *mygun = new gun;
mygun->doStuff();
return 0;
}
and you can compile and test using
g++ -o prg_name gun.cpp main.cpp && ./prg_name
I'm noob in C++, and I have the following header file (Header.h)
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
using namespace std;
class Predicate
{
public:
virtual void print() = 0;
};
class UnaryIntegerPredicate : public Predicate
{
public:
virtual void print();
};
class BiaryIntegerPredicate : public Predicate
{
public:
virtual void print();
};
#endif
and in another separate .cpp file (Source.cpp), I tried to implement the print method, but got an "expected an expression" error.
#include "stdafx.h"
#include "Header.h"
#include <iostream>
using namespace std;
UnaryIntegerPredicate::UnaryIntegerPredicate() : Predicate()
{
virtual void print()
{
cout << "int : boolean" << endl;
}
}
what is wrong here, thanks!
I see you are probably coming from a Java background. What you need is
void UnaryIntegerPredicate::print()
{
cout << "int : boolean" << endl;
}
You don't need the stuff surrounding that. Since you have already declared in your header that UnaryIntegerPredicate derives from Predicate, you don't mention that again in the implementation file. You show that the print method that you are writing is the print method of the UnaryIntegerPredicate class by prefixing the name of the method with the name of the class as I have shown above.
You also don't need the virtual keyword in the cpp file because that is already specified in the header file.
I'm watching some video tutorials on C++ and i know you must define a function / class before it is used or called. But I like having my main() function at the top, and everything else below the main function. I know if i define a function below the main function I must declare it before it is used, but what about a class? What do I need to put above my main function to use my class below the main function.
#include <iostream>
using namespace std;
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
I tried defining my class by placing this right before main():
class ClassOne;
but it doesn't work.
This is why header files are normally used in C++. When you're saying ClassOne one, the compiler needs to know what the class looks like to create an object of that type. It's not enough to know that the class exists somewhere (that is enough if all you want is a pointer). So the compiler needs to already have read the definition of the class.
Your class has to be defined before it is first used. Without putting it explicitly before main, the usual way is to create a header file. So you create ClassOne.h with the class declaration, and you have #include "ClassOne.h at the top of your file. In this situation the actual methods of the class would normally be in another source file, ClassOne.cpp.
A class MUST be "complete" when you create an instance of it. So there is no way you can use the class before you have defined the whole content of the class.
It is possible to do something like this:
class ClassOne;
ClassOne* make_class_one();
void use_class(ClassOne *x);
int main()
{
ClassOne* one = make_class_one();
use_class(one);
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
ClassOne* make_class_one()
{
return new ClassOne; // Bad idea, use uniqe_ptr, but I'm lazy.
}
void use_class(ClassOne *x)
{
x->coolSaying();
}
But in general, we don't want to do that.
One scenario where the class definition after the main() function makes sense:
#include <iostream>
using namespace std;
void f();
int main()
{
f();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
void f()
{
ClassOne one;
one.coolSaying();
}
(note: all other answers are correct, but you may find this useful)
I discovered this idiom to invert the order of main and secondary function classes. I use to share small code with colleagues, everybody expects the core of the code (i.e. main) to be on top so they can edit it quickly. It works with classes and functions (without need of declaration) of course. Usually I can leave the preamble (first #includes) because those have include guards in most cases.
#include <iostream>
using namespace std;
#ifdef please_see_definitions_below_main
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
#else
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
#define please_see_definitions_below_main
#include __FILE__
#endif
I use the tag please_see_definitions_below_main so it serves as comment also, but if you don't like it you can use something shorter, like AFTER.
You cannot create an actual instance of the type (variable, value member) until the type is fully defined, as its size is not known. There is no way around that, but there is a lot you can already do with a pointer to an incomplete type.