-2

I have read this thread here:

"Cannot allocate an object of abstract type" error

But I think it does not answer my case...

I have the files:

base.h

#ifndef BASE_H
#define BASE_H

#include <iostream>

using namespace std;

class Base {

    public:

        Base(){
            protected_member = 0;
        }
        Base(int pm_val): protected_member(pm_val) {cout << "created Base." << endl;}
        virtual ~Base(){cout << "deleted Base." << endl;}

        virtual int access_Base_pm() = 0;

    protected:

        int protected_member;

};

#endif

base.cpp (redudant I guess)

#include "base.h"
#include "derived.h"

derived.h

#ifndef DERIVED_H
#define DERIVED_H

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

using namespace std;

class Base;

class Derived: public Base {

    public:

        Derived(){cout << "created Derived." << endl;}
        ~Derived(){cout << "deleted Derived." << endl;}

        int access_Base_pm();

};

#endif

derived.cpp

#include "derived.h"
#include "base.h"

int Derived::access_Base_pm(){
    return protected_member;
}

When I run

main_1.cpp

#include <iostream>
#include "base.h"
#include "derived.h"

using namespace std;

int main(){

    Base* base;
    base = new Derived();
    cout << base->access_Base_pm() << endl;

}

everything seems to be fine.

But when I run

main_2.cpp

#include <iostream>
#include "base.h"
#include "derived.h"

using namespace std;

int main(){

    Base* base = new Base;
    base = new Derived();
    cout << base->access_Base_pm() << endl;

}

or

main_3.cpp

#include <iostream>
#include "base.h"
#include "derived.h"

using namespace std;

int main(){

    Base(5)* base;
    base = new Derived();
    cout << base->access_Base_pm() << endl;

}

I get "error: cannot allocate an object of abstract type ‘Base’"

Why? I don't get it. As it says in the other thread, I am accessing the object only via a pointer... what am I missing?

Community
  • 1
  • 1
lo tolmencre
  • 3,804
  • 3
  • 30
  • 60

2 Answers2

0

You cannot do a new of Base because that it is the abstract type.

Base* base = new Base;

is illegal

Base* base = new Derived();

is OK but for the reasons explained here : Is no parentheses on a constructor with no arguments a language standard? I prefer:

base = new Derived;

Also I don't know if this compiles :

Base(5)* base;

What is your intent with that statement ? Based on your comment it should be

Base* base = new Base(5);

or

Base base(5); 

if no pointer is needed, but this would not work because Base is abstract. And I cannot do it with Derived because then Derived has a missing constructor with a parameter. So you would need :

class Derived: public Base {

public:

    Derived(){cout << "created Derived." << endl;}
    Derived(){cout << "created Derived." << endl;}
    ~Derived(int pm_val):Base(pm_val){cout << "deleted Derived." << endl;}

    int access_Base_pm();

};

Base* base = new Derived(5);

or

Derived derived(5);
Base* base = &derived;
Community
  • 1
  • 1
Philip Stuyck
  • 7,344
  • 3
  • 28
  • 39
  • Thank you. But I don't really understand. I thought this would be the same as with any other class Classname* classinstance = new Classname. Can you elaborate or tell me where this explained? – lo tolmencre Mar 26 '15 at 20:31
  • `base = new Derived();` is by no means wrong if base has already been declared, which is the case here. `Base * base = new Derived();` is much better but its important to make that distinction. – dwcanillas Mar 26 '15 at 20:34
  • My intent with that statement was to create an instance of Base with parameter 5 that base is a pointer to. – lo tolmencre Mar 26 '15 at 20:37
  • Answering your edit: I still don't understand. The other thread says you need pointers to abstract classes. – lo tolmencre Mar 26 '15 at 20:56
  • You only need pointers to abstract types if you want to program towards those abstract types. A good OO program does just that. But this example is somewhat academic. – Philip Stuyck Mar 26 '15 at 21:10
  • which ~ do you mean ? but in any case as soon as you have a virtual method it is wise to create a virtual destructor too. – Philip Stuyck Mar 26 '15 at 21:38
  • I think I got it now. Thanks! I was talking about the destructor with parameters. You apparently just have put the ~ at the wrong place... right? – lo tolmencre Mar 26 '15 at 21:39
  • ok then please upvote this answer or mark it as solution, or both. – Philip Stuyck Mar 26 '15 at 21:40
0

main_1.cpp seems fine, because it is fine.

main_2.cpp does something that is fairly interesting

Base(5) * base;

Now, if Base(5) where some kind of type - which it is not - this would be a declaration of a pointer variable. However, Base(5) is actually a temporary variable (that is multiplied with an object with the name base that does not even exist in your code), created by constructing a variable of type Base and passing its constructor a 5. This is exactly what the question you linked explains as forbidden.

main_3.cpp blatantly does new Base which is exactly what the question you linked explores - Base is abstract and you try to create an object of that type.

danielschemmel
  • 10,885
  • 1
  • 36
  • 58