简体   繁体   中英

Externing a C++ class to avoid including its header file

I have created a static library for the following class, libtgbotengine.a and extern ed the class to be used in a different project.

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;

In a different project, I want to link libtgbotengine.a with the following cpp file. My goal is to not to include tgbotengine.h . Is extern ing myTgBotEngine help me achieve this?

project2.cpp

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

IMHO: What you want to do is not possible.

The header file of your library is like a blue print for your class.

Lets extend the example of 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
    // ...
}

Let's assume that TgBotEngine is a pure virtual class. Which the compiler does not know until you provide a header file:)

And a call to it like this:

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

What the compiler does to this line: tge.start(); is to call the second method of TgBotEngine which will be at index 1. Image it like this pseudo code: myTgBotEngine.[1]()

To determine the position of your method in the class you have to provide the header file.

The upcoming modules will probably allow what you want to do. Unfortunately, they are still experimental...

The only portable way I know to fully hide the implementation details is to split your class between a public interface and a private implementation. This is common to Java developpers.

Here it would look like:

  1. The interface part:

    The header

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

    Source:

     #include <tgbot/tgbotimpl.h> #include <tgbot/tgbot.h> std::unique_ptr<TgBotEngine> TgBotEngine::build(/*ctor parameters*/) { return std::make_unique<TgBotEngineImpl>(/*ctor parameters*/); }
  2. The implementation part

     #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 //... }

You can then use it that way:

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

int main() {
    std::unique_ptr<TgBotEngine> engine = TgBotEngine::build(/* ctor parameters*/);
    engine->start();
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM