문제

다른 파일에 정의된 CPP 클래스의 몇 가지 "정적" 메서드를 호출하고 싶지만 연결 문제가 있습니다.내 문제를 재현하는 테스트 케이스를 만들었고 이에 대한 코드는 아래와 같습니다.

(저는 C++을 처음 접했고 Java 경력이 있으며 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;
                }
        }
}

컴파일하려고 하면 다음 오류가 발생합니다.

$ 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

하지만 main.cpp에서 클래스 선언을 제거하고 #include "CppClass.cpp"로 바꾸면 제대로 작동합니다.기본적으로 이러한 선언을 별도의 .h 파일에 넣어서 사용하고 싶습니다.뭔가 빠졌나요?

도와 주셔서 감사합니다.

도움이 되었습니까?

해결책

아직 헤더 파일의 개념을 이해하지 못했기 때문에 Java 배경 지식을 갖고 있는 것이 분명합니다.Java에서 무언가를 정의하는 프로세스는 일반적으로 한 부분으로 이루어집니다.선언과 정의를 동시에 수행합니다.C/C++에서는 2단계 프로세스입니다. 선언 뭔가는 컴파일러에게 "이 유형에 뭔가가 존재하지만 실제로 어떻게 구현되는지 나중에 알려줄 것입니다"라고 알려줍니다. 정의 뭔가가 컴파일러에게 실제 구현 부분을 제공하고 있습니다.헤더 파일은 주로 선언에 사용되며 .cpp 파일은 정의에 사용됩니다.

헤더 파일은 클래스의 "API"를 설명하기 위해 존재하지만 실제 코드는 아닙니다.헤더 인라인이라고 하는 코드를 헤더에 포함할 수 있습니다.CppClass.cpp에 모든 것을 인라인 처리했습니다(좋지 않습니다. 헤더 인라이닝은 예외입니다). 그런 다음 C++의 이중 선언인 main.cpp에서 다시 클래스를 선언합니다.클래스 본문의 인라인 처리로 인해 메서드를 사용할 때마다 코드가 중복됩니다(이것은 소리 정신 이상의.참조 인라인에 대한 C++ 자주 묻는 질문 섹션 자세한 내용은.)

코드에 double 선언을 포함하면 컴파일러 오류가 발생합니다.클래스 코드를 그대로 두면 컴파일은 되지만 이제 main.cpp에 헤더와 같은 클래스 선언만 있으므로 링커 오류가 발생합니다.링커에서는 클래스 메서드를 구현하는 코드를 볼 수 없으므로 오류가 나타나는 것입니다.Java와 달리 C++ 링커는 사용하려는 개체 파일을 자동으로 검색하지 않습니다.XYZ 클래스를 사용하고 XYZ에 대한 개체 코드를 제공하지 않으면 단순히 실패합니다.

좀 봐주세요 Wikipedia의 헤더 파일 기사 그리고 헤더 파일 포함 패턴 (링크는 Wikipedia 기사 하단에도 있으며 더 많은 예제가 포함되어 있습니다)

간단히 말해서:

각 클래스에 대해 NewClass.h 및 NewClass.cpp 파일을 생성합니다.

NewClass.h 파일에 다음을 작성하십시오.

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

NewClass.cpp 파일에 다음을 작성하십시오.

#include "NewClass.h"

NewClass::NewClass() {
  // constructor goes here
}

int NewClass::methodA() {
  // methodA goes here
  return 0;
}

int NewClass::methodB() {
  // methodB goes here
  return 1;
}

main.cpp에서 다음을 작성하십시오.

#include "NewClass.h"

int main() {
  NewClass nc;
  // do something with nc
}

모두 함께 연결하려면 다음을 수행하십시오.

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

(gcc의 예)

다른 팁

클래스를 두 번 정의하고 있는데 이것이 작동하지 않을 것이라고 확신합니다.

다음과 같이 시도해 보십시오.

먼저 헤더 CppClass.h 파일:

// 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();
};

그런 다음 이를 구현하는 CppClass.cpp 파일:

// 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 */
}

그런 다음 기본 파일은 다음과 같습니다.

// main.cpp
#include "CppClass.h"

int main()
{
    /* main method body here */
}

나는 g++ 호출도 동일할 것이라고 믿습니다.

기본적으로 동일한 클래스를 두 번 선언할 수 없습니다.헤더 파일에서 클래스를 선언한 다음 cpp 파일에서 구현을 선언해야 합니다.모든 코드를 인라인으로 넣을 수도 있습니다. 하나의 헤더 파일에 클래스 선언그러나 당신처럼 두 번 선언하면 작동하지 않습니다.

그게 말이 되기를 바라요...

나는 당신이 다음과 같은 일을하고 싶어한다고 생각합니다 :

G ++ -C CPPCLASS.CPP G ++ -C Main.CPP G ++ -O GO MAN.O CPPCLASS.O

그러면 문제가 해결될 것입니다.

클래스 정의가 포함된 .h 파일을 만든 다음 해당 파일을 두 파일에 #include합니다.

물론 링커가 두 번째 소스 파일을 선택하지 않는 것 같습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top