程序哪个行为根据链接的类而变化

时间:2015-04-25 08:29:33

标签: c++ plugins linker extern

我不认为我的尝试是否足够值得这个术语"插件"但在这里我要做的是:

鉴于文件a.h,a.cp​​p和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时,代码打印&#34;我是B&#34;,在编译c.cpp时,代码打印&#34;我是C&#34;。

我想:

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

让测试不执行任何操作或执行默认操作。不需要简单。

1 个答案:

答案 0 :(得分:1)

这是一个使用弱符号的(非便携式)选项。

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;
}

如果您未与b.cpp或提供init功能的任何其他实体建立链接,则会使用main.cpp中的实体。如果您与b.cpp相关联,则会使用该定义。

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