Hi!

I was hoping for some advice on how best to create a single doubly-linked list which could contain all of the different types of classes I have.

This is the code I have written so far....

shape.h:

class Shape
{
public:

	Shape (int l=0, int h=0) : length(l), height(h) {}
private:

	int length;
	int height;

protected:

};

class Square : public Shape
{
public:

private:
	int side1;
	int side2;
	int side3;
	int side4;
}

class Triangle : public Shape
{
public:

private:

	int side1;
	int side2;
	int side3;
}

main.cpp:

#include <iostream>
#include "vessel.h"

using namespace std;

int main()
{

	int x;
	int y;

	cout << "enter the heighe" << endl;
	cin >> x;
	cout << "enter he length" << endl;
	cin >> y;

	Shape square(x,y);

	system ("PAUSE");
	return 0;
}

I've read loads these last couple of days on doubly-linked lists, but am not understanding the role of Templates.

Would use of a Template allow me to store the 3 different types of classes I have within a single doubly linked list?

I code I have written concerns me as I am creating an object of type Shape, but I'm thinking I should be storing pointers to the objects, not the objects themselves within the list.

If anyone can offer me some direction and advice on the matter it would be most appreciated :)

Many thanks!

Carrots.

Recommended Answers

All 5 Replies

sorry double post

Posting more than once is counterproductive.

Explicitly declare your doubly-linked list to store references to Shapes.

struct list {   //your structure
       Shape_data;
       Triangle_data;
       Square_data;
       list *link_front, *line_back
}

list *example;   //initializing your pointer
expample = new struct list;

Not quite sure what you mean by including your class in a structure; honestly I would just make a class that inherits all three but the above code is pretty generic as far as it goes. Functions like a normal linked list. You do not need pointers to the class objects inside the list because they are dynamic because list is a pointer, so you can delete all of them by deleting the pointer, just to keep something to track your list so you can free all the memory if you need to.

templates provide direct support for generic programming to represent a wide range of concepts.
firstly i would recommend you to do the double linked list program normally and then start programming normal template programs .
finally you can club these two concepts.

for a double linked list i guess you will have to make a class list which contains the left pointer and the right pointer and the information you need .

#include<iostream.h>
using namespace std;

class list 
{
        public :
                   class node 
                   {
                        node *lptr;
                         int info;  // here i have just used a integer u can   //have the information u have to put insidew the node u want to //create
                        node *rptr;
                      
                        public :
                          node ()
                          {
                                    lptr=rptr=NULL;
                           }
               };
               node *header;
                list()
                {
                 header = NULL;
                }
 };
struct list {   //your structure
       Shape_data;
       Triangle_data;
       Square_data;
       list *link_front, *line_back
}

list *example;   //initializing your pointer
expample = new struct list;

Not quite sure what you mean by including your class in a structure; honestly I would just make a class that inherits all three but the above code is pretty generic as far as it goes. Functions like a normal linked list. You do not need pointers to the class objects inside the list because they are dynamic because list is a pointer, so you can delete all of them by deleting the pointer, just to keep something to track your list so you can free all the memory if you need to.

First: I personally don't agree with this style. Whenever you declare a list, you immediately need space for all 3 kinds of Shapes. If you want your list to grow, you'd have to declare another list to point to that is also going to take up a lot of space in memory.

Second: The list doesn't have to be a pointer. It can be declared on the stack, but that's beside the point.

Third: I think the user was looking for a container-type that could store any type of the Shape specified and he wanted to avoid datum slicing.


I'm not near a compiler, but a solution to this problem could be something similar to this--

// assuming shape is defined
// intent: doubly-linked list that can contain any shape type

class Shape_DLL{

   private:
      class Node{
         private:
            Node* prior;
            Node* next;
            Shape* theShape;
      
         public:
            Node(Shape& ref) : prior(NULL), next(NULL), 
theShape(&ref){}

            Node(Shape& ref, Node* p, Node* n) : prior(p), next(n),
theShape(&ref){}

            void setPrior(Node* p){
               prior = p;
            }

            void setNext(Node* n){
               next = n;
            }
      };
      Node* root;

   public:
      Shape_DLL() : root(NULL){}

      ~Shape_DLL(){

         if(root)
               delete root;
      }      

      void addShape(Shape& item){
         // Logic here to add the item and appropriately
         // set the prior and next Nodes.
      }

      Shape& getShape(int index){
         // Logic here to get the item based on order of insertion
       
      }
};

--forgive me for any compile-time errors, but hopefully the point is clear. This solve the problem of both developing a doubly-linked list that can hold any kind of shape.


Original Poster: "Would use of a Template allow me to store the 3 different types of classes I have within a single doubly linked list?"

Yes, and the solution would look something like this--

#include <cstdlib>
#include <iostream>

// intent: doubly-linked list that can contain any type

template<class T>
class DoublyLinkedList{

   private:
      class Node{
         private:
            Node* prior;
            Node* next;
            T* type;
      
         public:
            Node(T& ref) : prior(NULL), next(NULL), 
type(&ref){}

            Node(T& ref, Node* p, Node* n) : prior(p), next(n),
type(&ref){}

            ~Node(){

               // assuming Nodes are dynamically allocated
               // should recursively delete the next node if it is not NULL
               if(next){
                  delete next;
                  next = NULL;
               }
            }

            void setPrior(Node* p){
               prior = p;
            }

            void setNext(Node* n){
               next = n;
            }

            T& getType(){
               return *type;
            }
      };
      Node* root;

   public:
      DoublyLinkedList() : root(NULL){}

      ~DoublyLinkedList(){
         // assuming that Node-pointers are dynamically allocated
         if(root){
               delete root;
               root = NULL;
         }
      }      

      void add(T& item){
         // Logic here to add the item and appropriately
         // set the prior and next Nodes.
      }

     
    //  T& get(int index){
         // Logic here to get the item based on order of insertion
       
   //   }
};

class Shape
{
public:

	Shape (int l=0, int h=0) : length(l), height(h) {}
private:

	int length;
	int height;

protected:

};

class Square : public Shape
{
public:

private:
	int side1;
	int side2;
	int side3;
	int side4;
};

class Triangle : public Shape
{
public:

private:

	int side1;
	int side2;
	int side3;
};

typedef DoublyLinkedList<Shape> DLL;

int main(){
   
   DLL shapeList; // A doubly linked list that can hold Shapes
   
    

   return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.