Search code examples
c++inheritancepure-virtual

Inheritance from a pure abstract class without default constructor


I have an pre-defined pure abstract class which I don't want to touch. It's declared like:

class A {
public:
  inline virtual ~A();
  A(const A&);
  A operator=(const A&);
  virtual void someMethod();
};

The class has no member variables & none of these functions are having any implementation, so it should be equal to: virtual void someMethod() = 0;. I want to implement this pure abstract class in my own class (because I need to add member variables to implement the function someMethod()) without changing the declaration from class A, but there are two problems:

1.) class A has no default constructor, but only a copy-constructor and assignment operator declared. So I won't be able to create an instance from my subclass, because A::A: no appropriate default constructor available.

2.) Even assuming, class A would have a default constructor declared and defined (If I add A(){} to the class declaration), I would get 2 linker errors for someMethod() and destructor from class A.

My own code looks like:

#include <memory>

class B : public virtual A {
public:
  B() {}
  inline virtual ~B() {}
  B(const B&) {}
  virtual void someMethod() override {}
};

int main(int argc, char*argv[]) {
  auto object = std::make_unique<B>(B());
  return 0;
}

Any advice what I'm doing wrong here?


Solution

  • As people in the comments mentioned, A is an impossible class. As it stands, you can only ever create a new A with a preexisting A, so there is no defined way to create an A. I would suggest removing the copy constructor declaration (and definition if you provided one somewhere). You can remove the assignment operator too, unless there actually is a definition for it. Since A has no fields, you might as well make the destructor pure virtual (see this answer about pure virtual destructors).

    virtual ~A() = 0;
    //outside class definition
    inline A::~A() {}
    

    If A has no functionality to include in some_method, just make it pure virtual:

    virtual void some_method() = 0;
    

    Also about your class:

    class B : public virtual A
    

    I don't think you need A to be a virtual base. Virtual in this context means that if another class inherited both A and B, it would have only one copy of A. These changes should make everything work.