라이브러리간에 C ++의 개체를 공유하는 방법

프레드릭

다음과 같은 프로그램이 있다고 가정합니다.

파일 main.cpp

#include "something.hpp"

int main(int argc, char* argv[]) {
    some = new Something();
    return 0;
}

다음 파일로 구성된 .so 라이브러리에 링크됩니다.

파일 logger.hpp

#include <iostream>

class Logger {
    public:
        Logger();
        void log(char);
        void set_name(char);
    private:
        char m_name;
};

파일 logger.cpp

#include "logger.hpp"

Logger::Logger() {}
void Logger::log(char msg) {
     std::cout << this->m_name << " : " << msg;
}
void Logger::set_name(char name) {
    this->m_name = name;
}

뭔가 파일을 작성하십시오.

#include "logger.hpp"

class Something {
    public:
        Something();
};

뭔가 파일 .cpp

#include "something.hpp"

Something::Something() {
    logger->log("hello !");
}

현재 코드는 정의되지 않았 으므로 something.cpp에서 실패 합니다. 을 추가하여이 문제를 해결할 수 있습니다. 하지만 이 라이브러리를 사용하는 프로그램 / 라이브러리에 생성 된 인스턴스가없는 경우 에만 새 인스턴스를 생성하고 싶습니다 . 인스턴스가 이미 생성 된 경우 . 그러나 인스턴스가 생성 되지 않은 경우 작동하지 않습니다 . 어떤 제안 (전혀 가능합니까?)?logger->log()loggerlogger = new Logger()Loggerextern Logger logger;

참고 : 이미 Gtkmm4 / Glibmm2.6을 사용하고 있습니다. 아마도 Gtk 또는 Glib를 사용하는 솔루션이있을 수 있습니다.

밥 모란

첫 번째 접근 방식 : 싱글 톤

주석에서 논의했듯이 Singleton 디자인 패턴사용하여 이를 달성 할 수 있습니다 . 그러나이 패턴에는 다음과 같은 몇 가지 단점 이 있습니다.

  • 싱글 톤은 글로벌 액세스를 허용합니다.
  • 싱글 톤은 단위 테스트가 어렵습니다.

양질의 소프트웨어를 작성할 때 진정한 문제입니다. 또한 특정 경우에 대해 모든 것이 적절하게 연결되어 있는지 확인하는 방법을 설명하는 이 답변 을 읽어서 싱글 톤의 여러 인스턴스로 끝나지 않도록하십시오.

두 번째 접근 방식 : 의존성 주입

위에서 언급 한 두 가지 문제를 해결하는 또 다른 방법 인 DI ( 종속성 주입 ) 를 설명하기 위해 여기에 답변을 게시하기로 결정했습니다 . DI를 사용하면 종속성을 생성하지 않고 매개 변수를 통해 주입합니다. 예를 들어 다음 대신 :

Something::Something() {
    auto logger = new Logger(); // Dependency creation (not injection)
    logger->log("hello !");
}

당신은 다음과 같은 것을 가질 것입니다.

Something::Something(Logger* p_logger) { // Logger dependency injected through p_logger
    p_logger->log("hello !");
}

DI는 '하나의 인스턴스'문제를 자체적으로 해결하지 않습니다 . 종속성을 한 번 (일반적으로에서 main) 생성 한 다음이를 사용하기위한 매개 변수로 전달하도록주의해야합니다. 그러나 글로벌 액세스 문제는 해결되었습니다.

종속성을 추상화하여 다른 수준으로 가져올 수 있습니다. 예를 들어 Logger클래스에 대한 인터페이스를 작성하고 대신 다음을 사용할 수 있습니다.

// Somewhere in your library:
class ILogger
{
public:
    virtual ~ILogger() = default;
    virtual void log(const std::string& p_message) = 0;
    virtual void set_name(const std::string& p_name) = 0;
};

// In Logger.hpp:
class Logger : public ILogger {
    public:
        Logger();

        void log(const std::string& p_message) override;
        void set_name(const std::string& p_name) override;

    private:
        std::string m_name;
};

// In something.hpp/cpp:
Something::Something(ILogger* p_logger) { // Logger dependency injected through p_logger
    p_logger->log("hello !");
}

이를 달성하려면 main다음과 같이 보일 수 있습니다 .

int main(int argc, char* argv[]) {
    // Here, you create your logger dependency:
    std::unique_ptr<ILogger> concreteLogger = std::make_unique<Logger>();
    concreteLogger->set_name("frederic");

    // Here, you inject it. From here on, you will inject it everywhere
    // in your code. The using code will have no idea that under the hood,
    // you really are using the Logger implementation:
    some = new Something(concreteLogger.get());

    // Note: if you use `new`, do not forget to use `delete` as well. Otherwise,
    //       check out std::unique_ptr, like above.

    return 0;
}

이것의 장점은 이제 로거에 대해 main신경 쓰지 않고 언제든지 로거의 구현을 변경할 수 있다는 것입니다. 단위 테스트를 원하는 경우에 대비하여 로거 모의를 만들 수도 있습니다 Something. 이것은 단위 테스트에서 싱글 톤을 처리하는 것보다 훨씬 더 유연하며, 용어 적으로 모든 종류의 (조사 / 해결하기 어려운) 문제를 생성합니다. 이것은 측면에서 위에서 언급 한 두 번째 문제를 해결합니다.

DI의 가능한 단점은 많은 매개 변수를 갖게 될 수 있다는 것입니다. 그러나 제 생각에는 싱글 톤을 사용하는 것보다 여전히 우수합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

CMake를 사용하여 Android 빌드에서 두 개의 C ++ 라이브러리를 컴파일하고 공유하는 방법

분류에서Dev

C ++ 객체 파일에 의존하는 CUDA 공유 라이브러리를 어떻게 컴파일합니까?

분류에서Dev

C ++에서 사용하려는 C 라이브러리의 라이브러리 경로를 환경에 추가하는 방법

분류에서Dev

Thunderbird에서 자신의 pkcs # 11 공유 라이브러리를로드하는 방법

분류에서Dev

C ++에 공유 라이브러리를 포함하는 방법은 무엇입니까? libORB_SLAM

분류에서Dev

라이브러리와 애플리케이션간에 공유되는 클래스를 선언하는 방법

분류에서Dev

Rcpp를 사용하여 C 라이브러리의 C 구조를 R에 노출하는 방법

분류에서Dev

C #에서 라이브러리를 사용하는 방법

분류에서Dev

C ++ : 두 개의 상호 의존적 인 공유 라이브러리를 만드는 방법은 무엇입니까?

분류에서Dev

C ++ 두 개의 공유 라이브러리를 main.cpp에 연결

분류에서Dev

C #의 개체 배열에서 개체를 제거하는 방법

분류에서Dev

C ++의 cmath 라이브러리에서 특수 함수를 호출하는 방법은 무엇입니까?

분류에서Dev

공유 라이브러리를 사용하는 디렉토리의 모든 라이브러리를 인쇄하는 방법은 무엇입니까?

분류에서Dev

간단한 C 라이브러리에 대한 cffi 래퍼를 생성하는 방법

분류에서Dev

C #과 Python 프로세스간에 바이트 배열의 메모리를 공유하는 방법

분류에서Dev

라이브러리 내부에서 라이브러리의 문자열 리소스를 참조하는 방법

분류에서Dev

여러 클래스간에 개체를 공유하는 방법

분류에서Dev

C # UserControl의 모든 개체를 이동하는 방법

분류에서Dev

공통 인터페이스를 공유하는 다른 개체에서 하나의 개체 초기화 C #

분류에서Dev

C ++에서 클래스 개체를 재정의하는 방법

분류에서Dev

C 라이브러리에 C ++ 라이브러리를 포함하는 방법은 무엇입니까?

분류에서Dev

C # x 유형의 개체에 대해 개체를 재귀 적으로 검색하는 방법

분류에서Dev

처리를위한 최소 라이브러리를 사용하여 왼쪽 및 오른쪽 채널에 대해 두 개의 FFT 개체를 만드는 방법

분류에서Dev

Visual Studio 코드에서 f2py 인터페이스에서 공유 라이브러리의 C 함수를 호출하는 Python 프로그램을 디버그하는 방법

분류에서Dev

주 실행 파일의 하위 폴더에 Qt C ++ 공유 라이브러리의 dll을 배포하는 방법은 무엇입니까?

분류에서Dev

C #에 대한 LDAP와 유사한 개체 구조를 제공하는 라이브러리가 있습니까?

분류에서Dev

공유 라이브러리를 다른 라이브러리에 삽입하는 방법은 무엇입니까?

분류에서Dev

다른 Python 버전간에 동적 라이브러리 포함 C (.so 파일)의 하위 호환성을 유지하는 방법

분류에서Dev

Javascript에서 C # 개체를 만드는 방법의 차이점

Related 관련 기사

  1. 1

    CMake를 사용하여 Android 빌드에서 두 개의 C ++ 라이브러리를 컴파일하고 공유하는 방법

  2. 2

    C ++ 객체 파일에 의존하는 CUDA 공유 라이브러리를 어떻게 컴파일합니까?

  3. 3

    C ++에서 사용하려는 C 라이브러리의 라이브러리 경로를 환경에 추가하는 방법

  4. 4

    Thunderbird에서 자신의 pkcs # 11 공유 라이브러리를로드하는 방법

  5. 5

    C ++에 공유 라이브러리를 포함하는 방법은 무엇입니까? libORB_SLAM

  6. 6

    라이브러리와 애플리케이션간에 공유되는 클래스를 선언하는 방법

  7. 7

    Rcpp를 사용하여 C 라이브러리의 C 구조를 R에 노출하는 방법

  8. 8

    C #에서 라이브러리를 사용하는 방법

  9. 9

    C ++ : 두 개의 상호 의존적 인 공유 라이브러리를 만드는 방법은 무엇입니까?

  10. 10

    C ++ 두 개의 공유 라이브러리를 main.cpp에 연결

  11. 11

    C #의 개체 배열에서 개체를 제거하는 방법

  12. 12

    C ++의 cmath 라이브러리에서 특수 함수를 호출하는 방법은 무엇입니까?

  13. 13

    공유 라이브러리를 사용하는 디렉토리의 모든 라이브러리를 인쇄하는 방법은 무엇입니까?

  14. 14

    간단한 C 라이브러리에 대한 cffi 래퍼를 생성하는 방법

  15. 15

    C #과 Python 프로세스간에 바이트 배열의 메모리를 공유하는 방법

  16. 16

    라이브러리 내부에서 라이브러리의 문자열 리소스를 참조하는 방법

  17. 17

    여러 클래스간에 개체를 공유하는 방법

  18. 18

    C # UserControl의 모든 개체를 이동하는 방법

  19. 19

    공통 인터페이스를 공유하는 다른 개체에서 하나의 개체 초기화 C #

  20. 20

    C ++에서 클래스 개체를 재정의하는 방법

  21. 21

    C 라이브러리에 C ++ 라이브러리를 포함하는 방법은 무엇입니까?

  22. 22

    C # x 유형의 개체에 대해 개체를 재귀 적으로 검색하는 방법

  23. 23

    처리를위한 최소 라이브러리를 사용하여 왼쪽 및 오른쪽 채널에 대해 두 개의 FFT 개체를 만드는 방법

  24. 24

    Visual Studio 코드에서 f2py 인터페이스에서 공유 라이브러리의 C 함수를 호출하는 Python 프로그램을 디버그하는 방법

  25. 25

    주 실행 파일의 하위 폴더에 Qt C ++ 공유 라이브러리의 dll을 배포하는 방법은 무엇입니까?

  26. 26

    C #에 대한 LDAP와 유사한 개체 구조를 제공하는 라이브러리가 있습니까?

  27. 27

    공유 라이브러리를 다른 라이브러리에 삽입하는 방법은 무엇입니까?

  28. 28

    다른 Python 버전간에 동적 라이브러리 포함 C (.so 파일)의 하위 호환성을 유지하는 방법

  29. 29

    Javascript에서 C # 개체를 만드는 방법의 차이점

뜨겁다태그

보관