指针和指向类数据成员的指针的抽象

Abstraction of pointer and pointer to class data member

本文关键字:指针 抽象 数据成员      更新时间:2023-10-16

我想你们很多人都熟悉类数据成员指针的用法。最常见的用法是当你有一个对象列表,并且用一个只知道数据成员的相对偏移量的函数处理它们时。

我有一个嵌套结构,在注册时,我只知道内部结构(b)相对于父结构(a)的相对偏移量。全局结构实例(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的指针,我想通过隐藏(aptr->*b_rel_ptr)在指针类中的差异来生成B*

更新:

总的来说,经过深思熟虑后,我需要为这个指针类提供三个独立的接口。

  1. 我需要能够分配一个val字符串的指针指向的位置
  2. 如果基指针尚未设置,则需要设置指针对象的基指针
  3. 我需要定义结构指针的概念,这样我就可以将基指针传播给它的所有成员

这些将是我需要的具体指针类:

  1. 绝对结构指针——一个全局结构指针
  2. 相对结构指针—结构
  3. 内部的结构指针
  4. 相对值指针——结构体
  5. 中的值指针
  6. 绝对值指针——一个值的位置已经已知的值指针

一旦我能够定义这个指针抽象的接口。我能够实现我所需要的,没有太多的麻烦。

////////////////////////////////////////////////////////////////////////////////
// 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;
};