c++中指向自身内部类的指针

Pointers to a class within itself in C++

本文关键字:内部类 指针 c++      更新时间:2023-10-16

我正在分析c++中的一些代码,我遇到了这个配置。

class jack {
  //rest of the class body here
  public:
    jack *a;
};

在这种配置中使用指针的理论是什么?

这里没有什么特别的理论

允许声明指向不完全类型的指针,包括正在声明的类型。因为class jack内部的指针指向class jack,这并不意味着指针指向同一个对象。

这是因为编译器实际上不需要知道指针的目标类型,因为指针基本上只是一个地址。首先,当你对指针做某些事情时,它需要是一个完整的类型(例如在你解引用它的时候,访问成员或方法,做指针算术等)。

允许这是必要的,以便允许构建广泛的数据结构,包括链表,树等。在C中,它也很有用,因为它允许通过不暴露编译单元外的结构的内容来隐藏数据(数据隐藏是通过在头文件中向前声明struct并在实现该结构的API的C文件中完整定义来完成的)。

包含指向自身指针的类在很多情况下都很有用。

但是,在我提出这些场景之前,需要了解的事实是:

仅仅是类的定义:

class jack {
//rest of the class body here
 public:
  jack *a;
};

不表示存在,除非存在Object:

jack obj;
创建类的

因此,这实际上意味着,当创建类jack的对象obj时,它将在其内部拥有一个指针a,该指针可能指向同一类的另一个对象。

现在,这可能是有用的如果:

  • 需要创建一个对象链,参见链表。

  • 一个对象可以关联到另一个相同类型的对象。例如:每个雇员可以有一个经理,其中经理本身也是雇员:

     class Employee {
     //rest of the class body here
      public:
       Employee *manager;
     }
    

和对象可以有如下关系:

    Employee salesManager;
    Employee salesWorker;
    salesWorker.manager = &salesManager;
  • 在处理不同的问题时,你会遇到许多其他人。

所以jack的对象可以指向该类的另一个对象。记住this是对象中指向self的指针,所以肯定不需要额外的指向self的指针。假设你创建了两个对象

jack jack1;
jack jack2;
jack1.a = &jack2;
jack2.a = &jack1;

现在对象彼此都知道了。因此,您不需要更高级别的容器来管理它们。这就是使用指向相同类或结构的指针的主要原因。在这个例子中,jack1可以告诉jack2你应该做一些事情。然后jack2可以做它的事情,然后要求jack1做其他事情。如果不使用这种方法,就必须保存一个指针/对象列表,然后通过迭代器访问对象并与之通信。你可以用这个机制做各种复杂的事情,从创建链表到FSMs。

典型的链表。链接列表是一个概念,您可以在其中构建一个列表,其中第一个元素指向第二个元素,第二个元素指向第三个元素,依此类推。最后一个元素不指向任何东西,即指针等于nullptr。列表的入口通常是指向第一个元素的指针(头)(如果列表为空,则为nullptr)。

// First element
jack* head = new jack();
head->a = nullptr;
// Second element
head->a = new jack();
head->a->a = nullptr;
//More general - insert element
jack* newElement= new jack();
newElement->a = nullptr;
if (head == nullptr)
{
    head = newElement;
}
else
{
    jack* tmp = head;
    while(tmp->a != nullptr)  // iterate the list to find last element
    {
        tmp = tmp->a;
    }
    tmp->a = newElement; 
}
// Remember to clean up when done
while (head != nullptr)
{
    jack* tmp = head;
    head = head-> a;
    delete tmp;
}

但是要使用std容器(vector, list等),而不是自己编写。