Question

I have a class interface called fstackbase.h and I'm making a simple stack, fstack1, that inherits from fstackbase. All of the functions in fstackbase.h are pure virtual and I have to implement them all in my fstack1.h. My question is, how can this be considered inheritance? I re-write every function declaration in fstackbase.h and then implement them in fstack1.cpp. Wouldn't I get the same result if I just skipped fstackbase.h all together?

I'm completely new to c++ and this implementation I made is a homework assignment and I had a hard time getting it to work and when I finally did I'm not even sure I'm doing it right since I don't see a difference between using inheritance or not in this case.

Any general comments or pointers about my code are welcomed as well as good links or other sources for c++ knowledge. I also apologise in advance for the code comments being in Icelandic:P.

This is the base class fstackbase:

// fstackbase.h
#ifndef _FSTACKBASE_H
#define _FSTACKBASE_H

class fstackbase {
public:
    // Notkun: delete p;
    // Eftir:  Búið er að eyða hlaðanum *p.
    virtual ~fstackbase() {};

    // Notkun: x.Push(r);
    // Fyrir:  fjöldi talna á hlaða x er minni en 1000.
    // Eftir:  Búið er að setja r ofan á hlaðann x.
    virtual void Push(double)=0;

    // Notkun: r = x.Pop();
    // Fyrir:  Hlaðinn x er ekki tómur.
    // Eftir:  Búið er að fjarlægja efstu tölu af hlaðanum x,
    //         og er hún í r.
    virtual double Pop()=0;

    // Notkun: n = x.Count();
    // Eftir:  n inniheldur fjölda talna á hlaðanum x.
    virtual long Count() const=0;
};

#endif

...And this is my stack interface fstack1.h:

// fstack1.h    
#include "fstackbase.h"
#ifndef _FSTACK1_H
#define _FSTACK1_H

class fstack1 : public fstackbase {
private:
    double *hladi;
    long count;
    // Fastyrðing gagna:
    //   hladi bendir á array sem inniheldur tölurnar á hlaðanum.
    //   count er fjöldi talna sem eru á hlaðanum.

public:
    // Notkun: fstack1 f;
    // Eftir:  f er nýr tómur hlaði, með
    //         minnisrými fyrir 1000 double tölur.
    fstack1();

    // Notkun: fstack f = x;
    // Fyrir:  x er gildi af tagi fstack1.
    // Eftir:  f er nýtt eintak af fstack1 sem er
    //         frumstillt sem afrit af x.
    fstack1(const fstack1& x);

    // Notkun: f = x;
    // Fyrir:  f er breyta af tagi fstack1,
    //         x er gildi af tagi fstack1.
    // Eftir:  f hefur fengið nýtt gildi og inniheldur
    //         nú afrit af gildinu x.
    // virtual const fstack1& operator=(const fstack1& x);

    // Erft frá fstackbase.h
    ~fstack1();

    // Erft frá fstackbase.h
    void Push(double d);

    // Erft frá fstackbase.h
    double Pop();

    // Erft frá stackbase.h
    long Count() const;
};
#endif

...And finally, this is the implementation of my stack in fstack1.cpp:

// fstack1.cpp
#include "fstackbase.h"
#include <iostream>    
using std::cout;
using std::endl;

fstack1::fstack1()
{
    hladi = new double[1000];
    count = 0;
}

fstack1::~fstack1()
{
    delete[] hladi;
    hladi = 0;
}

fstack1::fstack1(const fstack1& x)
{
    delete[] hladi;
    hladi = x.hladi;
    count = x.count;
}

// const fstack1& fstack1::operator=(const fstack1& x)
// {
//  delete[] hladi;
//  hladi = x.hladi;
//  count = x.count;
//  return *this;
// }

void fstack1::Push(double d)
{
    if (count < 1000) hladi[count++] = d;
    else cout << "Hladi er fullur!" << endl;
}

double fstack1::Pop()
{
    double temp = 0;

    if (count) temp = hladi[--count];
    else cout << "Hladi er tomur!" << endl;

    return temp;
}

long fstack1::Count() const
{
    return count;
}
Was it helpful?

Solution

What they've had you do is implement an interface.

It seems redundant and for the moment, in the assignment, it more or less is. Here's an example that shows you how it might be useful.

You start using this stack in your code; but since you made an interface, you pass around a pointer to the fstackbase which has all the methods that you need.

Now, you realize that sometimes you want a stack based on the array of 1000 like you have. That's fine. However in other parts of your code, you want a stack based on an std::vector. You make another class that derives from fstackbase. It is forced to implement those same methods. In the rest of your code, you only need to change the one line that instantiates the fstack1 to the new class fstack2. Since you defined and stuck to using your interface, the rest of the code will compile and work correctly.

Dr Dobbs article on interfaces

OTHER TIPS

My question is, how can this be considered inheritance?

Well, you are inheriting from a base class to create a sub class. That's the definition of inheritance. You usually use inheritance for two big reasons:

  • polymorphism
  • inherit functionality

In this case, since you are not inheriting any functionality in the base class, you are probably doing this for polymorphism.

If you just have 1 base class and 1 child class, you can't really see the benefits in this. But consider this:

class os {
public:
    virtual void start() = 0;
    virtual void turn_off() = 0;
};

class mac : public os {
public:
    virtual void start() { ... }
    virtual void turn_off() { ... }
};

class windows : public os {
public:
    virtual void start() { ... }
    virtual void turn_off() { ... }
};

You can now create algorithms to handle any operating system that inherits from os:

void mess_with(os& victim) {
    while (42) {
        victim.start();
        victim.turn_off();
    }
}  

Therefore you can call:

mac x;
windows y;
mess_with(x);
mess_with(y);

This is of course just an example, but you easily read a lot about inheritance here.

You implemented an abstract base class that defines an interface that will be inherited by all who use it, so they'll all have to follow the same interface in their implementations.

If you didn't use the inheritance in the derived class, difference implementations of the stack class all code have different members, types, etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top