[英]Abstraction of pointer and pointer to class data member
I think many of you are familiar with the usages of pointer to class data member. 我认为你们中的许多人都熟悉指向类数据成员的指针的用法。 The most common usage is when you have a list of objects and process them with a function that only knows the relative offset of the data member.
最常见的用法是当您有一个对象列表并使用仅知道数据成员的相对偏移量的函数来处理它们时。
I have a nested structure where at registration, I only know the relative offsets of the inner struct (b) with respect to the parent struct (A). 我有一个嵌套的结构,在注册时,我只知道内部结构(b)相对于父结构(A)的相对偏移量。 The global struct instance (a) has not yet been instantiated.
全局结构实例(a)尚未实例化。
At some point in the program, a will be instantiated and all the data members (including the sub struct (b)) will bind with the absolute locations of the global struct. 在程序中的某个时刻,将实例化a,所有数据成员(包括子结构(b))将与全局结构的绝对位置绑定。
Please see an example below 请看下面的例子
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
Now, I would like to abstract the notion of a pointer since I have a simple absolute reference which is A*
and I have a pointer to an inner struct B
which I would like to generate B*
by hiding the deference of (aptr->*b_rel_ptr)
inside a pointer class. 现在,我想抽象的指针的概念,因为我有一个简单的绝对参考,该参考
A*
和我有一个指针到内部struct B
我想生成B*
通过隐藏的顺从(aptr->*b_rel_ptr)
放在指针类中。
UPDATE: 更新:
In general, after some more thoughts, I need to have three separate interfaces to this pointer class. 通常,经过更多考虑之后,我需要针对此指针类具有三个单独的接口。
These will be the concrete pointer classes I need: 这些将是我需要的具体指针类:
Once I am able to define the interfaces to this pointer abstraction. 一旦我能够定义此指针抽象的接口。 I was able to implement what I needed without too much trouble.
我能够轻松实现所需的功能。
////////////////////////////////////////////////////////////////////////////////
// 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;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.