Problem Binding "Static" Methods in C ++

I want to call several β€œstatic” methods of the CPP class defined in another file, but I am having problems linking. I created a test script that recreates my problem, and the code for it is below.

(I am completely new to C ++, I come from the Java background, and I am a little familiar with C.)

// CppClass.cpp #include <iostream> #include <pthread.h> static pthread_t thread; static pthread_mutex_t mutex; static pthread_cond_t cond; static int shutdown; using namespace std; class CppClass { public: static void Start() { cout << "Testing start function." << endl; shutdown = 0; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); pthread_create(&thread, &attr, run_thread, NULL); } static void Stop() { pthread_mutex_lock(&mutex); shutdown = 1; pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mutex); } static void Join() { pthread_join(thread, NULL); } private: static void *run_thread(void *pthread_args) { CppClass *obj = new CppClass(); pthread_mutex_lock(&mutex); while (shutdown == 0) { struct timespec ts; ts.tv_sec = time(NULL) + 3; pthread_cond_timedwait(&cond, &mutex, &ts); if (shutdown) { break; } obj->display(); } pthread_mutex_unlock(&mutex); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); pthread_exit(NULL); return NULL; } void display() { cout << " Inside display() " << endl; } }; // main.cpp #include <iostream> /* * If I remove the comment below and delete the * the class declaration part, it works. */ // #include "CppClass.cpp" using namespace std; class CppClass { public: static void Start(); static void Stop(); static void Join(); }; int main() { CppClass::Start(); while (1) { int quit; cout << "Do you want to end?: (0 = stay, 1 = quit) "; cin >> quit; cout << "Input: " << quit << endl; if (quit) { CppClass::Stop(); cout << "Joining CppClass..." << endl; CppClass::Join(); break; } } } 

When I tried to compile, I get the following error:

  $ g ++ -o go main.cpp CppClass.cpp -l pthread
 /tmp/cclhBttM.o(.text+0x119): In function `main ':
 : undefined reference to `CppClass :: Start () '
 /tmp/cclhBttM.o(.text+0x182): In function `main ':
 : undefined reference to `CppClass :: Stop () '
 /tmp/cclhBttM.o(.text+0x1ad): In function `main ':
 : undefined reference to `CppClass :: Join () '
 collect2: ld returned 1 exit status

But if I remove the class declaration in main.cpp and replace it with #include "CppClass.cpp", it works fine. Basically, I want to place these ads in a separate .h file and use it. Did I miss something?

Thanks for the help.

+6
c ++ linker g ++
source share
5 answers

Obviously, you came from the Java background because you have not yet understood the concept of header files. In Java, the process of defining something is usually in one piece. You simultaneously declare and determine. In C / C ++, this is a two-step process. The declaration says something to the compiler "something exists with this type, but I will tell you later how it is implemented." Defining something gives the compiler the actual part of the implementation. Header files are mainly used for declarations, .cpp files for definitions.

Header files should describe the "API" of the classes, but not their actual code. You can include code in the header called a header. You included everything in CppClass.cpp (not good, nesting of headers should be an exception), and then you declare your class in main.cpp AGAIN, which is a double declaration in C ++. Embedding in the body of the class leads to code duplication every time you use the method (it just sounds crazy. See C ++ faq section onlining for more details .)

Including double declaration in your code gives a compiler error. Leaving a compromise on class code, but gives you a linker error, because now you only have a header type declaration in main.cpp. The compiler does not see code that implements class methods, so errors appear. Unlike Java, the C ++ linker will NOT automatically search for object files that it wants to use. If you use the XYZ class and do not pass the object code for XYZ to it, it just fails.

Please see the Wikipedia header file article and the Include Templates header file (the link is also at the bottom of the Wikipedia article and contains more examples)

In short:

For each class, generate the NewClass.h and NewClass.cpp files.

In the NewClass.h file write:

 class NewClass { public: NewClass(); int methodA(); int methodB(); }; <- don't forget the semicolon 

In the NewClass.cpp file write:

 #include "NewClass.h" NewClass::NewClass() { // constructor goes here } int NewClass::methodA() { // methodA goes here return 0; } int NewClass::methodB() { // methodB goes here return 1; } 

In main.cpp write:

 #include "NewClass.h" int main() { NewClass nc; // do something with nc } 

To tie it all together, do

g ++ -o NewClassExe NewClass.cpp main.cpp

(just an example with gcc)

+31
source share

You define the class twice, and I am sure that it does not work.

Try something like this:

First, the header of the CppClass.h file:

 // CppClass.h using namespace std; class CppClass { public: static void Start(); static void Stop(); static void Join(); private: void *run_thread(void *pthread_args); void display(); }; 

Then the CppClass.cpp file that implements it:

 // CppClass.cpp #include <iostream> #include <pthread.h> #include "CppClass.h" using namespace std; void CppClass::Start() { /* method body goes here */ } void CppClass::Stop() { /* method body goes here */ } void CppClass::Join() { /* method body goes here */ } void *CppClass::run_thread(void *pthread_args) { /* method body goes here */ } void CppClass::display() { /* method body goes here */ } 

Then your main file:

 // main.cpp #include "CppClass.h" int main() { /* main method body here */ } 

I believe the g ++ call will be the same.

Basically, you cannot declare the same class twice. You must declare the class in the header file and then declare the implementation in the cpp file. You can also put all inline code in one class declaration in a header file. But announcing it twice, like you, will not work.

Hope this made sense ...

+9
source share

I think you want to do something like:

g ++ -c CppClass.cpp g ++ -c main.cpp g ++ -o go main.o CppClass.o

This should solve the problem.

+2
source share

create an .h file with the class definition in it, and then # include this file in your 2 files.

+1
source share

Of course, it seems that the linker is not picking up your second source file.

0
source share

All Articles