外部 C++ 类以避免包含其头文件

问题描述

我为以下类创建了一个静态库,libtgbotengine.aextern将该类用于不同的项目。

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.hextern myTgBotEngine 是否可以帮助我实现这一目标?

project2.cpp

int main(){
    
    myTgBotEngine.start();
    
    return 0;
}

解决方法

恕我直言:你想做的事情是不可能的。

你的图书馆的头文件就像你班级的蓝图。

让我们扩展 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]()

要确定您的方法在类中的位置,您必须提供头文件。

,

即将到来的 modules 可能会允许您做您想做的事。不幸的是,它们仍处于实验阶段...

我所知道的完全隐藏实现细节的唯一可移植方式是在公共接口和私有实现之间拆分您的类。这对于 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:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...