我想很多人都熟悉指向类数据成员的用法。最常见的用法是当您有一个对象列表并使用只知道数据成员的相对偏移量的函数处理它们时。
我有一个嵌套结构,在注册时,我只知道内部结构(b)相对于父结构(A)的相对偏移。全局结构实例(a)尚未实例化。
在程序的某个时刻,将实例化一个,并且所有数据成员(包括子结构(b))将与全局结构的绝对位置绑定。
请参阅下面的示例
struct A {
int a1;
int a2;
struct B {
int b1;
int b2;
}b;
}
descA.register(&A::a1,"a1");
descA.register(&A::a2,"a2");
descA.register(&A::b,descB);
...
descB.register(&B::b1,"b1");
descB.register(&B::b2,"b2");
A a; // create instance of nested struct
descA.bind(a);
// a1,a2,b requires the base pointer of a
// b1,b2 requires the base pointer of b
现在,我想抽象一个指针的概念,因为我有一个简单的绝对引用,A*
,我有一个指向内部struct B
的指针,我想生成{{} 1}}将B*
的deference隐藏在指针类中。
更新:
一般来说,经过一些想法后,我需要有三个独立的接口来指向这个指针类。
这些将是我需要的具体指针类:
答案 0 :(得分:0)
一旦我能够定义这个指针抽象的接口。我能够毫不费力地实现我的需求。
////////////////////////////////////////////////////////////////////////////////
// Pointer abstraction
////////////////////////////////////////////////////////////////////////////////
// interfaces
class Reference {
public:
virtual ~Reference() {}
virtual void assign(std::string val) = 0;
};
template<typename BT>
class BasePtr {
public:
virtual void setBase(BT* ptr) = 0;
virtual bool isBaseSet() { return false; }
};
template<typename ST>
class StructPtr {
public:
virtual void addPtr(BasePtr<ST>* ptr) = 0;
virtual void notify() = 0;
};
// implementation
template<typename T>
class AbsStructPtr : public Reference,
public BasePtr<T>,
public StructPtr<T> {
public:
AbsStructPtr() {}
~AbsStructPtr() {}
void assign(std::string val) {
throw std::runtime_error("struct pointer: cannot assign to struct");
}
void setBase(T* p) {
ptr = p;
}
void addPtr(BasePtr<T>* ptr) {
pointers.push_back(ptr);
}
void notify () {
for(size_t i=0; i<pointers.size(); i++) {
pointers[i]->setBase(ptr);
}
}
protected:
T* ptr;
typedef std::vector<BasePtr<T>*> PointerVec;
PointerVec pointers;
};
template<typename T, typename PT>
class RelStructPtr : public Reference,
public BasePtr<PT>,
public StructPtr<T> {
public:
RelStructPtr(T PT::*ptr) : memptr(ptr), baseptr(NULL) {}
~RelStructPtr() {}
void assign(std::string val) {
throw std::runtime_error("struct pointer: cannot assign to struct");
}
void setBase(PT* p) {
baseptr = p;
}
void addPtr(BasePtr<T>* ptr) {
pointers.push_back(ptr);
}
void notify () {
T* ptr = &(baseptr->*memptr);
for(size_t i=0; i<pointers.size(); i++) {
pointers[i]->setBase(ptr);
}
}
protected:
T PT::*memptr;
PT* baseptr;
typedef std::vector<BasePtr<T>*> PointerVec;
PointerVec pointers;
};
template<typename T, typename PT>
class RelValPtr : public Reference,
public BasePtr<PT> {
public:
RelValPtr(T PT::*ptr) : memptr(ptr), baseptr(NULL) {}
~RelValPtr() {}
void assign(std::string val) {
assigner.assign(val);
}
void setBase(PT* p) {
baseptr = p;
}
protected:
T PT::*memptr;
PT* baseptr;
Assigner<T> assigner;
};
template<typename T>
class AbsValPtr : public Reference,
public BasePtr<T> {
public:
AbsValPtr(T* ptr) : valptr(ptr) {}
~AbsValPtr() {}
void assign(std::string val) {
assigner.assign(val);
}
void setBase(T* p) {
throw std::runtime_error("Base pointer is set");
}
bool isBaseSet() { return true; }
protected:
T* valptr;
Assigner<T> assigner;
};