行为根据链接的 类 而改变的程序
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",并允许您通过不使用全局变量来管理初始化(这里不重要,但是一旦您充实了您的插件系统就会变得更加棘手).
我认为我尝试的东西不够花哨,配得上这个词 "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",并允许您通过不使用全局变量来管理初始化(这里不重要,但是一旦您充实了您的插件系统就会变得更加棘手).