Я создал статическую библиотеку для следующего класса, libtgbotengine.a и extern отредактировал класс, который будет использоваться в другом проекте.

tgbotengine.h

#include <tgbot/tgbot.h>
// Other headers
// ...
class TgBotEngine{
public:
    // Class constructors and functions
    // ...
    void start();
    
private:
    TgBot::Bot m_bot;
    std::vector<TgBot::BotCommand::Ptr> m_commands;
    // Other members
    // ...
}

extern TgBotEngine myTgBotEngine;

В другом проекте я хочу связать libtgbotengine.a со следующим файлом cpp. Моя цель - не включать tgbotengine.h. Помогает ли мне в этом extern ing myTgBotEngine?

project2.cpp

int main(){
    
    myTgBotEngine.start();
    
    return 0;
}
0
user578 20 Май 2021 в 09:44

2 ответа

Лучший ответ

Предстоящие модули, вероятно, позволят вам делать то, что вы хотите. К сожалению, они все еще экспериментальные ...

Единственный известный мне переносимый способ полностью скрыть детали реализации - разделить ваш класс между общедоступным интерфейсом и частной реализацией. Это обычное дело для разработчиков Java.

Вот это будет выглядеть так:

  1. Интерфейсная часть:

    Заголовок

     // Other headers
     // ...
     class TgBotEngine {
     public:
         // public functions
         // ...
         virtual void start() = 0;
         static std::unique_ptr<TgBotEngine> build(/*ctor parameters*/);
     }
    

    Источник:

     #include <tgbot/tgbotimpl.h>
     #include <tgbot/tgbot.h>
    
     std::unique_ptr<TgBotEngine> TgBotEngine::build(/*ctor parameters*/) {
         return std::make_unique<TgBotEngineImpl>(/*ctor parameters*/);
     }
    
  2. Реализационная часть

     #include <tgbot/tgbot.h>
     // Other headers
     // ...
     class TgBotEngineImpl: public TgBotEngine {
     public:
         // Class constructors and functions
         // ...
         void start();
    
     private:
         TgBot::Bot m_bot;
         std::vector<TgBot::BotCommand::Ptr> m_commands;
         // Other members
         // ...
     }
    

Затем вы можете использовать его так:

#include "tgb.h"
#include <memory>

int main() {
    std::unique_ptr<TgBotEngine> engine = TgBotEngine::build(/* ctor parameters*/);
    engine->start();
    ...
}
1
Serge Ballesta 20 Май 2021 в 08:07

ИМХО: То, что вы хотите делать, невозможно.

Заголовочный файл вашей библиотеки похож на чертеж вашего класса.

Давайте расширим пример TgBotEngine:

class TgBotEngine{
public:
    // ...
    virtual void someMethod() = 0;    // for this example this is the first method
    virtual void start() = 0;         // for this example this is the second method
    virtual void anotherMethod() = 0; // for this example this is the third method
    // ...
}

Предположим, что TgBotEngine - чистый виртуальный класс. Что компилятор не знает, пока вы не предоставите файл заголовка :)

И призыв к нему такой:

void callBot(TgBotEngine& tge)
{
    tge.start();
}

Что делает компилятор с этой строкой: tge.start(); - это вызвать второй метод TgBotEngine, который будет иметь индекс 1. Изобразите его как этот псевдокод: myTgBotEngine.[1]()

Чтобы определить положение вашего метода в классе, вам необходимо предоставить файл заголовка.

1
Yunnosch 20 Май 2021 в 07:42