-2

I have a treatment parent class, and two children, inner treatment and outer treatment. I need to create a single linked list that contains both of the children nodes. I'm not allowed to use templates, or built in lists.

The problem I'm facing is the type of the next ptr, the only solution I found is to create a base node parent type, and put the two children inside it, plus a type variable to know which kind of node it is. Something like this:

enum node_type = {inner, outer};
struct treatment_node{

    Inner_Treatment t1;
    Outer_treatment t2;
    struct treatment_node *next;
    node_type treatment_type;

}

I'll know which class to access based on the treatment type. Would this work?

MichaelX
  • 202
  • 1
  • 9
  • 1
    Have you heard of [Polymorphism](https://stackoverflow.com/questions/5854581/polymorphism-in-c)? – scohe001 Dec 11 '17 at 18:59
  • _"Would this work?"_ Totally depends on your use case, and how you plan to create `Inner_Treatment` and `Outer_treatment` and handle them uniformly in processing. – user0042 Dec 11 '17 at 19:01
  • @scohe001 Yes, I wouldn't be able to create the list without using it. But I don't see how it relates to the type of the `next` ptr? – MichaelX Dec 11 '17 at 19:05
  • 2
    @MichaelX if you make `next` of type base class pointer, then you could have a list of a mix of your two child class objects. With polymorphism they'd still act like different class objects even though you'd have the same type of pointer. This is what I was trying to hint at. – scohe001 Dec 11 '17 at 19:15
  • 1
    Michael, @scohe001 is suggesting a structure something like this: https://ideone.com/GNOz7j – user4581301 Dec 11 '17 at 19:32

1 Answers1

1

As polymorphysm goes, you can use the same wording as in your question, but put a different meaning to the word 'base'. So, you can create a base treatment class and inherit your inner and outer classes from it:

class treatment_node {
    treatment_node *next;
public: 
    virtual std::string getTreatment()  = 0;
    ...
};

now your outer and inner:

class Outer_treatment : public treatment_node {
    ... members ...
public:
    std::string getTreatement() override {...}
};


};
class Inner_treatment : public treatment_node {
    ... members ...
public:
    std::string getTreatement() override {...}
};

Now you can put both on the list of treatement_nodes.

Serge
  • 11,616
  • 3
  • 18
  • 28
  • I already have a treatment parent class, and two treatment children (they contain ints, chars, and another class). Are you saying I should create another treatment parent? I'm not sure if I follow. These are the classes if you're interested https://pastebin.com/P7mDAW6A – MichaelX Dec 11 '17 at 20:01
  • in your example your `treatement_node` class is a container which has objects of other classes as members. It does not make much sense. Object-oriented programming is based on notion of polymorphysm and inheritance, which i showed in the example. The `base` class is something which is **common** between two other classes with ability to allow differences. You can create a list which knows about the 'common' part only. Read about polymorphysm to get a more elaborated explanation. – Serge Dec 11 '17 at 20:15
  • 1
    @MichaelX your treatment classes all extend from a common base, but the Nodes (`struct Inside_node {`, `struct Outside_node {`) do not. One possible solution is `struct node { treatment * t; node *next; };` Now everyone uses the same node and the node contains a pointer to a polymorphic object. – user4581301 Dec 11 '17 at 21:00
  • @user4581301 But can `Treatment *t` point to a child of `Treatment`? – MichaelX Dec 11 '17 at 21:08
  • 1
    Yep. That's about half of the point of polymorphism. Anything that "is-a" (inherits from) `Treatment` can be pointed at by a `Treatment *`. You don't know what it really is and you don't need to know. If you DO need to know, you should probably rethink the design, but there are cases where it happens. – user4581301 Dec 11 '17 at 21:21
  • @user4581301 I'll need to be able to access the children's data from the list, so I guess this won't work. Thank you regardless. – MichaelX Dec 12 '17 at 00:23
  • You may not have to directly access child class data (encapsulation suggests you should not have direct access to it anyway). Look into virtual functions and the visitor pattern as good alternatives that operate without knowing which subclass you're working with. – user4581301 Dec 12 '17 at 00:28
  • 1
    In the above example i have a `virtual` function `getTreatement` defined in the base class. It is overridden in child classes and could do different things there and return data. So, calling `t->getTreatement()` will do different job and return different data for different implementation of the class. If this is not satisfactory for you, you can alwahs cast the base class to the child and get data this way. – Serge Dec 12 '17 at 02:08