简体   繁体   English

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

[英]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. 通常,经过更多考虑之后,我需要针对此指针类具有三个单独的接口。

  1. I need to be able to assign a val string to the location pointed to by the pointer 我需要能够将val字符串分配给指针所指向的位置
  2. I need to set the base pointer of a pointer object if the base pointer is not already set 如果尚未设置基本指针,则需要设置指针对象的基本指针
  3. I need to define the notion of a struct pointer so I can propagate the base pointer to all its members 我需要定义结构指针的概念,以便可以将基本指针传播到其所有成员

These will be the concrete pointer classes I need: 这些将是我需要的具体指针类:

  1. absolute struct pointer - a global struct pointer 绝对结构指针-全局结构指针
  2. relative struct pointer - a struct pointer inside a struct 相对结构指针-结构内部的结构指针
  3. relative value pointer - a value pointer inside a struct 相对值指针-结构内部的值指针
  4. absolute value pointer - a value pointer where the location of the value is already known 绝对值指针-已知值位置的值指针

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM