开发者

Is it possible to create such C++ macros that would wrap your standard (inherited) class into an application?

开发者 https://www.devze.com 2023-03-26 10:09 出处:网络
So we have simple interface base class: class animal { public: animal(int age) : age_(age) { } virtual ~animal(void) {

So we have simple interface base class:

class animal {
public:
  animal(int age) : age_(age) {
  }
  virtual ~animal(void) {
  }
  virtual std::string get_name(void) {
    return "A generic animal";
  }
  int get_age(void) {
    return age_;
  }
protected:
  int age_;
};

And we want ti inherit from it with a class like this:

#include "animal.hpp"
#include "some_includes_for_our_shared_libs.hpp"

class puma : public animal {
 public:
  puma(int age) : animal(age) {}
  virtual std::string get_name() {
    return "puma";
  }
};

If we are creating a library - shared or static its ok for us just to inherit from it, but when we want to create an application we'd have to create a some main function and probably add some includes. I want to create some macros that would allow me to create such main in case class is compiled not into shared library.

I hepe it could look like

// puma.cpp
#include "FILE_WITH_MACROS.hpp"
ANIMAL_MACROS_NAME_HERE class puma : public animal {
 public:
  puma(int age) : animal(age) {}
  virtual std::string get_name() {
    return "puma";
  }
};
//end of puma.cpp

And that macros would get class name and create a main that would create and call our class as if it was calling general animall class or just add includes for "animal.hpp" and "some_includes_for_our_shared_libs.hpp" .

So in case of shared lib class would be turned by macros into

#include "animal.hpp"
#include "some_includes_for_our_shared_libs.hpp"

class puma : public animal {
 public:
  puma(int age) : animal(age) {}
  virtual std::string get_name() {
    return "puma";
  }
};

And in case of application class would be tu开发者_如何学运维rned by macros into

#include <iostream>
#include "animal.hpp"


class puma : public animal {
 public:
  puma(int age) : animal(age) {}
  virtual std::string get_name() {
    return "puma";
  }
};

int main()
{
int default_age = 4;
puma *an_animal = new puma(default_age);
std::cout << "anmal "<< an_animal->get_name << " created. Its age is " << an_animal->get_age << std::endl;
std::cin.get();
}

Usage: imagine we have a service-base class and we created new-service. Our main server app supports extensions so new-service can be connected to it in cese it is compiled into shared library. But what If we want to make our service into a stand alone server? than we would need such macros to wrap it with main and possibly add or remove some #includes.

my point is to make it so that any class that inherits from my special interface could me compiled into shared library or exequtable with out any code changes.


int main()
{
int default_age = 4;
SERVICECLASS *an_animal = new SERVICECLASS(default_age);
std::cout << "anmal "<< an_animal->get_name << " created. Its age is " << an_animal->get_age << std::endl;
std::cin.get();
}

Then compile with (your compiler's equivalent of) -DSERVICECLASS=puma, or have a file called something like "config.h" which is included by main, and that you can edit without having to edit any other code.

Then you can define your animal classes however you like. If you want to define classes like this:

#define STRINGIZE_(ARG) #ARG
#define EXPAND_AND_STRINGIZE(ARG) STRINGIZE(ARG)

class SERVICECLASS: public animal {
 public:
  SERVICECLASS(int age) : animal(age) {}
  virtual std::string get_name() {
    return EXPAND_AND_STRINGIZE(SERVICECLASS);
  }
};

then you can. But surely your classes do more than just hard-code a string, so I'd expect different animals to need separate definitions even if they have a certain amount in common.


I'd just make it so that the main() is trivial. Like

int main()
{
    int default_age = 4;
    return puma(default_age).run();
}

and leave it at that.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号