行为根据链接的 类 而改变的程序

Program which behavior changes depending on classes it is linked against

我认为我尝试的东西不够花哨,配得上这个词 "plugin" 但我想做的是:

给定文件 a.h、a.cpp 和 main.cpp,我想创建其他文件,例如:

g++ -o test main.cpp a.cpp b.cpp

导致测试程序执行某些操作,并且

g++ -o test main.cpp a.cpp c.cpp

做点别的。

这部分我已经在做,请参见下面的代码。 我的问题是:是否可以

 g++ -o test main.cpp a.cpp

做一些默认行为?我尝试了几件事,但我总是以未定义的方式结束。

我目前的代码:

// a.h    

#ifndef A_H_
#define A_H_

class A {
 public:
  A();
  ~A();
  virtual void print()=0;
};

#endif


// a.cpp

#include <iostream>
#include "a.h"

A::A(){}
A::~A(){}


// b.h

#include "a.h"

class B: public A {
 public:
  B();
  ~B();
  void print();
};


// b.cpp

#include <iostream>
#include "b.h"

B::B(){}
B::~B(){}
void B::print(){
  std::cout << "I am B" << std::endl;
}

A* a = new B();


//  code in c.h and c.cpp similar to the one in b.h and b.cpp
//   just "B" replaced by "C"

// main.cpp

#include "a.h"

extern A* a;

int main(){
  a->print();
}

针对 b.cpp 编译时,代码打印 "I am B",针对 c.cpp 编译时,代码打印 "I am C".

我愿意:

g++ -o test main.cpp a.cpp

让测试要么什么都不做,要么做一个默认行为。不需要简单。

这是一个使用弱符号的(不可移植的)选项。

a.h

struct A {
  public:
    virtual void print() = 0;
};

struct Dummy: A {
  void print() override {};
};

A* init();

main.cpp

#include "a.h"

A* __attribute__((weak)) init()
{
  return new Dummy;
}

int main()
{
  A* a = init();
  a->print();
}

b.cpp

#include "a.h"
#include <iostream>

struct B: A
{
  void print() override {
    std::cout << "B" << std::endl;
  }
};

A* init()
{
  return new B;
}

如果您不link使用b.cpp或任何其他提供init功能的实体,将使用main.cpp中的实体。如果你 link 和 b.cpp,将使用那个人的定义。

这种为 init 函数提供了一个 "default implementation",并允许您通过不使用全局变量来管理初始化(这里不重要,但是一旦您充实了您的插件系统就会变得更加棘手).