I'm having a bit of trouble with a C++ program I'm working on. I've created an abstract class with a single pure virtual method. Since the class has no variables or implemented methods, I've stored the class in a header file without an .cpp implementation file (there isn't any need for one).
The method is:
virtual void handleEvent() = 0;
The issue is when I inherit from that class and implement the method:
virtual void handleEvent(); (.h file)
void handleEvent(){.....} (.cpp file)
I get a compiler error (using g++):
(.rodata._ZtV10Engine[vtable for Engine]+0x8): undefined reference to Engine::handleEvent()
The file is being included in the Engine header class. Any ideas why this isn't working?
I think you forgot to put the class qualifier in the .cpp implementation. It should probably read:
void Engine::handleEvent() { ... }
I'd say deus-ex-machina399 probably has it right, but it could also be your calling conventions (would have to be different compiler settings between at least 2 different .cpp files). Try using __cdecl or __stdcall (or whatever the correct name is for the g++ compiler, try looking at this list)
Related
For C programs, I know I need .h, and .cpp to allow multiple .h to be read and compiled together but linked later.
However, for C++, I don't want to break up the class member function declaration and definition to two parts. Although it is the typical C++ way, I am trying to merge member function declaration and definition in one header file. I saw some people doing that. I would like to know if there is any problem to do this.
I know all members defined in .h class definition are then inline functions, but can they be non-inline in any way? Will compiler be controllable so that they don't have to be inline, for example, when the function is huge?
The VS2015 intellisense shows error when the 2s is in a member function defined in header file, but doesn't show that in cpp file. But it compiles. Is it showing that I am doing it wrong, or it's a bug for VS2015? I deleted the sdf, restarted the project, as long as copy the function into the .h file, it shows a read line under std::this_thread::sleep_for(2s);
see
class testtest {
void tryagain() {
using namespace std::chrono_literals;
auto twosec = 2s;
std::this_thread::sleep_for(2s);// problem is here
}
};
Is compiling faster if we separate the .h and .cpp?
My final compiler would be g++4.9.2, and I am using VS2015 to test build. The final code will run on an ARM with 1GB RAM on Linux.
I don't intend to argue about wich style is better, but hope to focus on whether it works, and what are the trade offs.
It is perfectly fine to place all implementation code in the .h file if you want, it usually depends on the situation. It's usually good practice to split up the interface and implementation even if all the code is in the .h file by doing something like this
class MyClass {
public:
void doSomethingUseful();
};
....
void MyClass::doSomethingUseful() {
// code goes here....
}
Not all functions will automatically be inlined, the compiler usually decides what to inline or not. Larger functions will likely not be inlined even if they're in the header. You can use the inline keyword to give a hint to the compiler that you'd like the function to be inlined but this is no guarantee (also as a small aside, functions marked as inline in a .cpp file will be inlined, but only when called from other functions within that same .cpp file)
Compile times will be slower with more code in the .h file so it's best to try and reduce the amount of code in them as much as possible. I guess in your case though it shouldn't be that noticeable.
I hope that is of some help! :)
You can put defines around functions to prevent them being implemented more than once
header file:-
class MyClass {
public:
void doSomethingUseful();
};
// inline functions
....
// non inline function
#ifdef MYCLASSCPP
void MyClass::doSomethingUseful() {
// code goes here....
}
#endif
Then define MYCLASSCPP in just one CPP file. (or complier parameter).
I have created a function library that I want to create a DLL from and create an export library. Creating the DLL is not the problem.
The problem is that, I do not want the developer/user to look inside the header file as the code is not optimized and some of it looks a mess even though it works.
Is there anyway I can include the contents of the header file within another DLL so that the header file will then be hidden or is there a way to compile the header to Binary?
Win32, visual studio 2010, 'c/c++'.
First, remove the code from the header: just declare the functions and specify the classes (i.e. no code in there):
//header
void my_ignomous_function(int);
class my_ignomous_class {
public:
my_ignomous_class();
~my_ignomous_class();
bool my_ignomous_member(my_ignomous_class &x);
private:
// unfortunately, you have to give these details.
};
If this is not sufficient, you could use the pimpl idiom: in your class you use a pointer to an object that is used for the implementation. The advantage is that you can just declare the implementation class without any details in the header. The details are only needed in the implementation.
//header
class my_nice_class {
public:
my_nice_class()
~my_nice_class()
bool my_nice_member(my_nice_class &x);
private:
class my_horrible_secret_class *impl;
};
The other approach is to fune-tune your design, so that you've no longer anything to hide ;-)
As already mentioned you have to separate Declaration and Definition [1]
Declaration in Header (.h), export only functions the developers need [2] - no need for a .def file.
The user has to know the Declarations of the functions he is using. So he needs the header.
Definition (function body - implementation) in Source file (.cpp)
Maybe you can split it up into more header/source - pairs so that the header for the Developers solely contains the clean "interface" of your library - the exported function.
https://www.cprogramming.com/declare_vs_define.html
https://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport?view=msvc-170
I created a class and have some outside methods in a Functions.h header (think thats the problem). Anyway, when ever I try to use any type of C-style function in the class implementation file; even blank ones, I get a compiler/ liker error. I am new to this and don't understand what the problem is. I'm thinking I can't use the .h file, but I am able to use global vars and directives in the class file.
Where am I suppose to declare my outside functions? In what kind of file?
My guess is that you fully define the functions (including implementation) in a header file, and include that from multiple source files; and that the errors you forgot to describe say something about "multiple definitions" or "duplicate symbols":
// Header file
void some_function() {
// do some stuff
}
If that is the case, you need to either move the definitions into a source file, leaving just declarations in the header, so they only have a single definition:
// Header file
void some_function();
// Source file
void some_function() {
// do some stuff
}
or declare the definitions inline, which allows them to be included in more than one source file:
// Header file
inline void some_function() {
// do some stuff
}
If that isn't the problem, please post some example code and error messages so we don't have to guess what's happening.
You have c++ as a tag. Perhaps these functions are C++ functions but you're trying to get at them from an Obj-C file? If that's the case, you either need to turn them into C functions, or you need to use Obj-C++ (which has the .mm extension instead of .m).
My homework assignment is telling me to declare a class inline, but I've only heard of declaring functions inline. What does an inline class declaration do, and how do you achieve it?
I think they are just saying that your classes should go in the header, and for convenience all the class methods should be declared inline in the class itself, instead of putting the class methods out-of-line or into a separate CPP.
It's slightly ambiguous but that's how I'd interpret it.
Comparing functions and classes:
A function can have a declaration and a definition:
ReturnType FunctionName(Parameter1, Parameter2); // a function declaration
ReturnType FunctionName(Parameter1, Parameter2) // a function definition
{
// do something
return ReturnType;
}
The function declaration gives all the information anyone needs who wants to call the function.
The function definition allows the compiler to generate machine code so that when someone calls the function there will be instructions somewhere in the executable that will be called.
This generated code exists only once in the executable. Usually you would put the function definition in a .cpp file (or .c if you're using C, this applies there too), which is compiled and linked into the executable. If that .cpp file isn't linked you will get a linker error saying FunctionName not found or something like that.
If you put the function definition in a header file it is more than likely that the header will be used in multiple places in your system, and included into other .cpp files. This will produce the opposite problem at link time FunctionName already defined in this, that, or the other object file.
So, functions usually aren't defined in header files because the header is usually included in multiple .cpp files so would end up producing duplicated object code.
With classes however it's slightly different. You have two different ways of defining a function for a class. One way is similar to how functions are defined above:
//myleanklass.h
class MyLeanKlass
{
public:
void perform();
};
//myleanklass.cpp
void MyLeanKlass::perform()
{
// Sing, dance, and play the piano
}
Just as with a free function we could have put the definition in the header file, as long as it wasn't included in more than one .cpp file. Otherwise we'd get a similar linker error again void MyLeanKlass::perform already defined ... This scenario is not the norm though. You usually declare classes so that they can be reused through a system. So the header will be included in multiple places and lead to linker errors.
Just to be clear, we could have put the definition in the header file, but not inline. You wouldn't be able to include this header multiple times in your system:
class MyLeanKlass
{
public:
void perform();
};
void MyLeanKlass::perform()
{
// Sing, dance, and play the piano
}
Finally then, we get to the answer to the question. You can define class functions in the header file as long as they are within the class declaration. This is called inline definition. Even if the header is included in multiple .cpp files it won't lead to multiple definitions in compilation units and won't cause linker errors.
//myleanklass.h
class MyLeanKlass
{
public:
void perform()
{
// Sing, dance, and play the piano
}
};
However, there are problems with this approach:
Inlining class functions is likely to make compilation take longer as the compiler will still compile every repeated definition of class functions and only throw away the duplicates at link time.
Making changes to class functions causes a recompilation of any .cpp file which includes it, again leading to longer re-compilation times.
Sometimes it just won't be possible. If a class uses another class and that uses the other class, you're going to have a cyclic dependency and it won't be possible to define everything inline. You can solve that by just putting the problem functions into a separate .cpp file.
Background
I have a project named PersonLibrary which has two files.
Person.h
Person.cpp
This library produces a static library file. Another project is TestProject which uses the PersonLibrary (Added though project dependencies in VS008). Everything worked fine until I added a non-member function to Person.h. Person.h looks like
class Person
{
public:
void SetName(const std::string name);
private:
std::string personName_;
};
void SetPersonName(Person& person,const std::string name)
{
person.SetName(name);
}
Person.cpp defines SetName function. When I try to use SetPersonName from TestProject, I get error LNK2005: already defined. Here is how I used it
#include "../PersonLibrary/Person.h"
int main(int argc, char* argv[])
{
Person person;
SetPersonName(person, "Bill");
return 0;
}
Workarounds tried
1 - I have removed the Person.cpp and defined the whole class in Person.h. Error gone and everything worked.
2 - Changed the SetPersonName modifier to static. Like the below
static void SetPersonName(Person& person,const std::string name)
{
person.SetName(name);
}
Questions
Why the code shown first is not working as I expected?
What difference static made here?
What is the approapriate solution for this problem?
Thanks
You either have to
move SetPersonName's definition to a .cpp file, compile and link to the resulting target
make SetPersonName inline
This is a well known case of One Definition Rule violation.
The static keyword makes the function's linkage internal i.e. only available to the translation unit it is included in. This however is hiding the real problem. I'd suggest move the definition of the function to its own implementation file but keep the declaration in the header.
When you compile you're library, its lib file contains a definition for SetPersonName. When you compile your program that uses the library, since it includes the header, and you've written the code inline in the header it also compiles in a definition for SetPersonName. Two definitions for the same function aren't (generally) allowed. The static keyword tells the compiler that the function shouldn't be exposed outside of the current translation unit (discrete piece of code you are compiling), so the definition in the library isn't visible to the linker.
The appropriate solution to this problem depends on your goals. Header files with static function declarations is almost never what you want. From a design standpoint I would recommend getting rid of SetPersonName altogether, and just use Person::SetName.
However, failing that, I would implement it much like you've done for the rest of your functionality, declarations in the header, and implementation in the .cpp. Inline functions associated with a library will tend to diminish many of the advantages of using a library in the first place.
By declaring the function static you are scoping it to the current translation unit, so in effect you have added a new SetPersonName function in your main file, and would be calling that not the one defined in the library.
The correct solution is to declare SetPersonName as extern in person.h and implement it in person.cpp
Person.h
extern void SetPersonName(Person& person,const std::string name);
Person.cpp
void SetPersonName(Person& person,const std::string name)
{
person.SetName(name);
}
The function SetPersonName will be compiled into each objectfile that includes the Person.h file, thus making the linker seeing several functions and giving the error.
By writing static you state that the function will only be visible within a single objectfile. You will still get several functions in you binary but now you will not get the errors.
Try to write inline before the function like
inline void SetPersonName(Person& person,const std::string name)
{
person.SetName(name);
}
...because the function is pretty simple it is OK I think to have it as an inline. An inline will place the necessary code where the function is used, without actually creating a function to be called.
A solution would be to make that function a static method. That will stop the "already defined" errors.
I had a similar situation as described clearly by #logan-capaldo above.
A CPP source file (myfile.cpp) contained a function MyFunction. When building, this got compiled into myfile.obj. But the main CPP file (main.cpp) also included myfile.cpp, so the function MyFunction was being included/compiled/linked twice, leading to the "LNK2005 already defined" error.
This is messy but I didn't have time to fix it properly. The quickest fix (in VS Express 2012) was to right-click myfile.cpp in Solution Explorer, go to Properties and change Excluded From Build to Yes. I guess this prevents one of the OBJ files from being created and/or linked and so removes the error.
For anyone landing here dealing with this error in a Qt project, make sure you don't have any non-signal functions defined under signals: in your header files.
Incorrect, throws LNK2005 on Foo::promiseData():
class Foo : public QObject {
Q_OBJECT
public:
explicit Foo(QObject* parent = nullptr);
signals:
void dataReady(QList<QObject*> data) const;
void promiseData() const; // <-- This function is not supposed to be a signal.
Correct:
class Foo : public QObject {
Q_OBJECT
public:
explicit Foo(QObject* parent = nullptr);
void promiseData() const;
signals:
void dataReady(QList<QObject*> data) const;