如何将这个层次结构包含在包含调用其C等价物的成员函数的C ++类中?
C经常使用大量的黑客来获得继承层次结构。其中之一是在Linux内核中大量使用的container_of
宏。我正在使用以这种样式编写的现有C库,我想将结构层次结构调整为由C ++包装的结构。为了便于说明,我将使用以下结构层次结构。
#include <cstdio>
#include <iostream>
#include <cstddef>
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
extern "C" {
struct a;
typedef void (*callback_t)(struct a *self);
struct a {
callback_t cb;
};
struct b {
struct a a;
const char * name;
};
void handle_event(struct a *self) {
self->cb(self);
};
void process_event(struct a * a) {
handle_event(a);
}
void some_a_operation(struct a * self) {
printf("some operation called on a @ %p\n", self);
}
void some_b_operation(struct b * self) {
printf("some operation called on a @ %p\n", self);
}
void c_callback_handler(struct a * a)
{
struct b * b = container_of(a, struct b, a);
printf("%s\n", b->name);
}
};
如果上述代码没有变化,我可以看到以下方法。
这解决了struct a
重复的先前示例问题,但代价是显着复杂。
class A {
public:
A() {
A_Wrap = new A_wrapper {{A::Cb}, this};
A_Obj = &A_Wrap->a_member;
}
virtual ~A() {
delete A_Wrap;
}
void OperationA() {
some_a_operation(A_Obj);
}
virtual void InstanceCb() {};
// member functions access struct a via A_Obj
protected:
struct A_wrapper {
a a_member;
A * A_member;
};
A_wrapper* A_Wrap;
a * A_Obj;
private:
static void Cb(a * self) {
A_wrapper * a_wrapper = container_of(self, A_wrapper, a_member);
a_wrapper->A_member->InstanceCb();
}
};
class B: public A {
public:
B() {
delete A_Wrap;
B_Wrap = new B_wrapper {{&B::Cb}, this};
A_Obj = &B_Wrap->b_member.a;
B_Obj = &B_Wrap->b_member;
}
virtual ~B() {
A_Wrap = nullptr;
delete B_Wrap;
}
void OperationB() {
some_b_operation(B_Obj);
}
virtual void InstanceCb() {
std::cout << "B class" << std::endl;
};
// member functions access struct a via A_Obj
protected:
struct B_wrapper {
b b_member;
B * B_member;
};
B_wrapper * B_Wrap;
b * B_Obj;
private:
static void Cb(a * self) {
b * b_contained = container_of(self, b, a);
B_wrapper * b_wrapper = container_of(b_contained, B_wrapper, b_member);
b_wrapper->B_member->InstanceCb();
}
};
int main(int argc, char **argv) {
// C usage
const char * b_name = "b struct";
struct b b_cexample = {
{c_callback_handler}, b_name
};
process_event(&b_cexample.a);
some_a_operation(&b_cexample.a);
some_b_operation(&b_cexample);
// C++ usage example
B b_cppexample;
b_cppexample.InstanceCb();
b_cppexample.OperationA();
b_cppexample.OperationB();
}