How do I inherit an abstract class in C++?

Asked

Viewed 1,729 times

1

In Java we have the possibility to create abstract classes, but without the possibility of instantiating them, but we can create and instantiate a class that inherits the attributes and methods of an abstract parent. In C++ this is done in a different way and I would like to know how it is done?

So far I have tried to do what was said above (or almost), create an abstract class and inherit its its attributes and methods for another class that will be instantiable. Follows the code:

Mother. h

#ifndef MOTHER_H_INCLUDED
#define MOTHER_H_INCLUDED

#include <string>

typedef std::string str;

class Mother{

    private:

        str test01;
        str test02;

        unsigned test03;

    public:

        virtual void setTest01(str teste01_)=0;
        virtual void setTest02(str teste02_)=0;

        virtual void setTest03(unsigned teste03_)=0;

    public:

        virtual str getTest01()=0;
        virtual str getTest02()=0;

        virtual unsigned getTest03()=0;

};

#endif // MOTHER_H_INCLUDED

//Red Hat

Mother.cpp

#include "Mother.h"

void Mother::setTest01(str test01_){

    test01=test01_;
}

void Mother::setTest02(str test02_){

    test02=test02_;
}

void Mother::setTest03(unsigned test03_){

    test03=test03_;
}

str Mother::getTest01(){

    return test01;
}

str Mother::getTest02(){

    return test02;
}

unsigned Mother::getTest03(){

    return test03;
}

Daughter. h

#ifndef DAUGHTER_H_INCLUDED
#define DAUGHTER_H_INCLUDED

#include "Mother.h"

class Daughter: virtual public Mother{



};

#endif // DAUGHTER_H_INCLUDED

main.cpp

#include "Mother.h"
#include "Daughter.h"

int main(void){

    Daughter tst;

    return 0;
}

When I compile the program with GNU g++:

error: cannot declare variable ĩtst' to be of Abstract type ĩDaughter' Daughter. h|6|note: because the following virtual functions are Pure Within 'Daughter':|

...among other errors and warnings

  • The idea of having abstract methods in the base class is so that they have no implementation in that base class and only in derived classes. Not to mention that it’s very unusual for a getter or Setter to be abstract.

  • @Isac Living and learning! did not know this business of getter and Setter be unusual as abstracts. Thank you for your comment.

  • @Isac "The idea of having abstract methods in the base class is so that they have no implementation in that base class and only in the derived classes." - So in this case I am incorrect in implementing my abstract base class?

  • It would be incorrect, the idea is not to implement in the base class. If you are going to implement in the base class then do not put them abstract, removing the =0 in each of them.

  • @Isac Blz! So I’m going to implement in Daughter. h? More how do I do this?

  • Not in your case it would make sense to leave the implementation in the Mother.h but without being abstract, because it would hardly want to give another different implementation in the derived class. But it’s a little hard to understand what you intend to do in such an exoteric example.

  • @Isac Cara...but the business here is not if it makes sense and yes I know how I will make the inheritance of an abstract class, it is not at all that the name of the variables has "test" everywhere.

Show 2 more comments

1 answer

2

I disagree with the comment that getters/setters abstract are unusual. Actually in C++ the mechanism of getters/setters are unusual, but where they are used is common use, if it makes sense, the class be really abstract, which often does not, then nor would be unusual case, would be wrong.

I totally agree that an example of a class with abstract names and without a clear definition of what the object is can’t model anything right. What can be right for one case can be very wrong for another. If you do something that makes no sense then you are wrong and should not do.

Both Isac and I and several other users here are committed to teaching right, we may make mistakes, but we try to get it right all the time. It would be irresponsible of us to accept something wrong knowing it is. So there are some solutions depending on what the object is.

Abstract class

The class is not abstract or at least part of it is not abstract (yes, it is possible to have an abstract part and another not, of course the class will be considered abstract and not installable with only an abstract method, but the rest of it need not be abstract:

class Mother {
    string test01;
    int test03;
    public:
        virtual string getTest01();
        virtual void setTest01(string teste01);
        virtual int getTest03();
        virtual void setTest03(int teste03);
};

string Mother::getTest01() { return test01; }
void Mother::setTest01(string test01) { this.test01 = test01; }
int Mother::getTest03() { return test03; }
void Mother::setTest03(int test03) { this.test03 = test03; }

Daughter. h

class Daughter: virtual public Mother {}; //só faz sentido se fizer mais alguma coisa

Interface

If you want the methods to be abstract it makes no sense to have attributes, then we can turn this class into an interface:

class Mother {
    public:
        virtual string getTest01() = 0;
        virtual void setTest01(string teste01) = 0;
        virtual int getTest03() = 0;
        virtual void setTest03(int teste03) = 0;
};

Daughter. h

class Daughter: virtual public Mother {}; //não muito, mas aqui até faz sentido

string Daughter::getTest01() { return test01; }
void Daughter::setTest01(string test01) { this.test01 = test01; }
int Daughter::getTest03() { return test03; }
void Daughter::setTest03(int test03) { this.test03 = test03; }

I put in the Github for future reference.

I simplified it because if it is an abstract example there is no reason to put more than the minimum necessary. I could have taken the Teste03, I didn’t do it to show that I use int (almost always the use of unsigned is a mistake and when it is not used unsigned int (programming for you to understand is easy, for everyone to understand is more difficult). I also used it to show that it is customary to group the methods by what they are and not by what they do. You have to leave next what is related.

And I still used string because that typedef only serves to cause problems of readability and eat some mistake unintentionally.

Of course I took out parts of the code that are not necessary for understanding the problem since it is too abstract an example.

I did not make an example of an abstract class (instead of an interface) because the example is too abstract, but it would be possible to have attributes in cases where it makes sense (not this).

I’ve made other cosmetic improvements, but important.

  • What’s the difference between putting the function only as virtual and putting it as virtual but with a "=0" at the end?

  • virtual lets the function be overwritten, = 0 makes it not have implementation.

  • Ok, in this case it would not make sense to put '=0' at the end of a virtual function if you want to implode this function in another class???

  • I didn’t understand the doubt.

  • Sorry! I messed up the balls. 'What I meant is whether to put the case when we put '=0' at the end of a function we are saying to it to be a final method?

  • No, it’s the exact opposite of that, something that doesn’t have an implementation can never be final, although this does not exist in C++.

  • In C++ an abstract class can contain logic(code)?

  • 1

    It is demonstrated in the answer.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.