HairBears
HairBears

Reputation: 13

C++ Inheritance pure virtual functions

my problem is: How do I implement pure virtual functions in an inherited class? It always says i didn't implement the only function, but I tried to do it. So where is my mistake?

My code:

A.h:

class A {
public:
    A();
    virtual std::pair<A*, A*> f1(const A& o) const=0;
    virtual ~A();
};

B.h:

#include "A.h"

class B : public A {
public:
B();
virtual ~B();
virtual std::pair<A*, A*> f1(const A& o);
};

B.cpp:

#include "B.h"

B::B() : A() {}
B::~B() {}
std::pair<A*, A*> B::f1(const A& o) {
   A* K1=new B();
   A* K2=new B();
   return std::make_pair (K1, K2);
}

I get following error:

B.cpp: In member function ‘virtual std::pair<A*, A*> B::f1(const A&)’:
B.cpp:14:16: error: cannot allocate an object of abstract type ‘B’
    A* K1=new B();
                ^
In file included from B.cpp:1:0:
B.h:4:7: note:   because the following virtual functions are pure within ‘B’:
 class B : public A {
       ^
In file included from B.h:1:0,
                 from B.cpp:1:
A.h:10:28: note:    virtual std::pair<A*, A*> A::f1(const A&) const
  virtual std::pair<A*, A*> f1(const A& o) const=0;
                            ^
B.cpp:15:16: error: cannot allocate an object of abstract type ‘B’
    A* K2=new B();
                ^
In file included from B.cpp:1:0:
B.h:4:7: note:   since type ‘B’ has pure virtual functions
 class B : public A {
       ^

Also: What is correct, A* K1=new A(); or new B(); ?

Upvotes: 1

Views: 553

Answers (3)

Charlie
Charlie

Reputation: 1592

In B, your function needs to be virtual std::pair<A*, A*> f1(const A&) const; or it's a different function, not overriding the one from A.

(If you're using a C++11 compiler, do std::pair<A*, A*> f1(const A&) const override; and it becomes clear to the reader that you intended to override the function.)

Upvotes: 3

Mooing Duck
Mooing Duck

Reputation: 66961

Lets' put those two side by side and look closer:

A: virtual std::pair<A*, A*> f1(const A& o) const=0; 
B: virtual std::pair<A*, A*> f1(const A& o);

Well, I see a difference, one of these is a const function, and the other is not. That makes them two different functions. Since the const function was never overloaded, B is still abstract, like A, and cannot be instantiated.

A* K1 = new A(); //would give you an A, if A weren't abstract.  Do you want an A or B?
A* K1 = new B(); //gives a B object, stored as a pointer to an A interface.

I also highly recommend using std::unique_ptr where you currently have owning raw pointers. They'll prevent headaches later.

Upvotes: 3

David G
David G

Reputation: 96845

Your override has to match in cv-qualification. You're missing a const here:

std::pair<A*, A*> B::f1(const A& o) /* [const] */

Since it doesn't override and your base class method is pure virtual, your derived class becomes abstract. You can't instantiate objects of abstract type.

You have to add const to both the declaration and definition. Also, to make sure it overrides, use the keyword override:

std::pair<A*, A*> f1(const A& o) override; // error since it does not override

Upvotes: 3

Related Questions