0

What are use cases for self-referential types?

By self referential types, I mean:

class T { 
  T *ptr; // member variable that references the type of the class
};
bitmask
  • 32,434
  • 14
  • 99
  • 159
Ivin Polo Sony
  • 355
  • 3
  • 17
  • 5
    Because there's a use case for them. – Jonathan Grynspan Aug 24 '12 at 16:13
  • In your example the pointer is private which makes the usefulness of it more questionable. By default you cannot use it in a linked list unless you expose it through a getter or something similar. Is this intentional in your question or did you mean for the pointer to be public? – Avada Kedavra Aug 24 '12 at 16:19
  • @AvadaKedavra: Are you kidding? Members are usually private. The type is obviously not supposed to be complete. – bitmask Aug 24 '12 at 16:23
  • @bitmask: Kidding? No. In the code above the member is private. The answers below are using either a stuct (making it public by default) or a class and the public keyword. So, the class used by the OP exposes the member variable differently than in the types used in the current answers. I think it is important to know if the OP intend for the pointer to be private (in which case I find it harder to actually see the usefulness of it). – Avada Kedavra Aug 24 '12 at 16:28
  • 1
    One example could be the Singleton Design Pattern : http://stackoverflow.com/questions/1008019/c-singleton-design-pattern – Marius Gherman Aug 24 '12 at 16:39
  • @AvadaKedavra: You would typically implement member functions that access the private member variable. It wouldn't be good OOP if you dealt with `T` using only free functions. So I really don't get what you're talking about. – bitmask Aug 24 '12 at 16:43
  • The member function *ptr is in the private area only. It is used to refer to an object of its own type(class T). A public member function could be used to access it. @AvadaKedavara – Ivin Polo Sony Aug 25 '12 at 13:33

2 Answers2

2

It is one of the most efficient ways to build linked lists or tree hierarchies.

#include <iostream>

class linked_ints {
public:
  linked_ints() : next(nullptr), x(0) {}
  linked_ints* next;
  int x;
};

void print(linked_ints* b) {
  if(b == nullptr) return;
  do {
    std::cout << b->x << std::endl;
  } while((b = b->next));
}

int main()
{
  linked_ints x, y, z;
  x.next = &y; y.next = &z;

  print(&x);

  return 0;
}
pmr
  • 58,701
  • 10
  • 113
  • 156
2

One example I can think of are linked lists.

The example borrowed from here:

#include<iostream>
struct Node{
  int data;
  Node* next;
};
void InsertAfter(Node **head, int value){
  if(*head==NULL){
    Node* temp=NULL;
    temp = new Node;
    temp->data = value;
    temp->next = NULL;
    *head = temp;
  }else{
    Node *temp = new Node;
    temp->data = value;
    temp->next = (*head)->next;
    (*head)->next = temp;
  }
}
void DeleteAfter(Node **head){
  if(*head==NULL){
    return;
  }else{
    Node *temp = NULL;
    temp = (*head)->next;
    (*head)->next = (*head)->next->next;
    delete temp;
    temp=NULL;
  }
}
int DeleteAll(Node **head,int value){
  int count=0;
  Node *p = NULL;
  Node *q = (*head);
  if(*head==NULL){
    count =0;
  }else{
    while((q)!=NULL){
      if((q)->data==value){
        Node *temp = NULL;
        temp = q;
        if ( p!=NULL){
          p->next = q->next;
        }else{
          (*head) = q->next;
        }
        q = q->next;
        delete temp;
        temp = NULL;
        ++count;
      }else{
        p = q;
        q = q->next;
      }
    }
  } 
  return count;
}
void DisplayList(Node *head){
  if(head!=NULL){
    std::cout << head->data << "\n";
    while(head->next!=NULL){
      std::cout <<  head->data << "\n";
      head = 
      head->next;
    }

    std::cout << "\n\n";
}
int main(){
  Node *head=NULL;
  InsertAfter(&head,10);
  InsertAfter(&head,10);
  InsertAfter(&head,20);
  InsertAfter(&head,10);
  DisplayList(head);
  DeleteAfter(&head);
  DisplayList(head);
  int a = DeleteAll(&head,10);
  std::cout << "Number Of Nodes deleted 
                having value 10 = " << 
                a <<"\n\n";
  DisplayList(head);
  return 0;
}
BЈовић
  • 62,405
  • 41
  • 173
  • 273