对行为根据其所链接的类而变化的程序

Program which behavior changes depending on classes it is linked against

本文关键字:变化 程序 链接      更新时间:2023-10-16

我不认为我尝试的东西足够花哨,配得上"插件"一词,但在这里我想做的是:

给定文件 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();

主.cpp

#include "a.h"
A* __attribute__((weak)) init()
{
  return new Dummy;
}
int main()
{
  A* a = init();
  a->print();
}

乙.cpp

#include "a.h"
#include <iostream>
struct B: A
{
  void print() override {
    std::cout << "B" << std::endl;
  }
};
A* init()
{
  return new B;
}

如果您不与b.cpp或任何其他提供init功能的实体链接,则将使用main.cpp中的实体。如果您与b.cpp链接,则将使用该定义。

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