I do not think what I attempt is fancy enough to deserve the term "plugin" but here what I am trying to do:
Given files a.h, a.cpp and main.cpp, I would like to create other files such as:
g++ -o test main.cpp a.cpp b.cpp
results in a test program doing something, and
g++ -o test main.cpp a.cpp c.cpp
does something else.
This part I already have working, cf code below. My issue is: would it be possible to have
g++ -o test main.cpp a.cpp
do some default behavior? I tried several things, but I always end up with something undefined.
Code I have so far:
// 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();
}
When compiling against b.cpp, code prints "I am B", when compiling against c.cpp, code prints "I am C".
I would like:
g++ -o test main.cpp a.cpp
to have test either do nothing or do a default behavior. Does not need to be simple.
Here's a (non-portable) option using weak symbols.
struct A {
public:
virtual void print() = 0;
};
struct Dummy: A {
void print() override {};
};
A* init();
#include "a.h"
A* __attribute__((weak)) init()
{
return new Dummy;
}
int main()
{
A* a = init();
a->print();
}
#include "a.h"
#include <iostream>
struct B: A
{
void print() override {
std::cout << "B" << std::endl;
}
};
A* init()
{
return new B;
}
If you don't link with b.cpp
or any other entity that provides an init
function, the one in main.cpp
will be used. If you link with b.cpp
, that one's definition will be used.
This sort of provides a "default implementation" for the init
function, and lets you manage initialization by not using globals (not important here, but can get more tricky once you flesh out your plugin system).