Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoke abstract method in super class, and implement it in subclass in C++?

In Java it's possible to write an abstract, super class with unimplemented, abstract methods and non-abstract methods which invoke the abstract methods. Then in the subclass are the abstract methods implemented. When you then make an instance of the subclass, the super class uses the implementations in the subclass. How do I accomplish this in C++?

Here is what I mean, but in Java:

SuperClass.java

public abstract class SuperClass {

    public SuperClass() {
        method();
    }

    private void method() {
        unimplementedMethod();
    }

    protected abstract void unimplementedMethod();
}

SubClass.java

public class SubClass extends SuperClass {

    public SubClass() {
        super();
    }

    @Override
    protected void unimplementedMethod() {
        System.out.println("print");
    }

    public static void main(String[] args) {
        new SubClass();
    }
}

Would be awesome if you showed me how this is accomplished in C++. :)

like image 211
Daniel Jonsson Avatar asked Jan 18 '23 11:01

Daniel Jonsson


1 Answers

In general, what you are looking for, is the virtual keyword. In a nutshell virtual declares the intent that this method can be overriden. Note that such a method can still have an implementation- virtual just makes it overrideable. To declare an "abstract method", you can say declare intent of please provide an implementation in the derived class with = 0, as shown below. Such methods are called pure virtual in C++.

However, there are some caveats that you should watch out for. As pointed out in a comment below, you were calling method() from within the SuperClass constructor. Unfortunately this is not possible in C++, due to the order in which objects are constructed.

In C++ a derived class constructor immediately calls it's superclass constructor before allocating its members or executing the body of the constructor. As such, the members of the base class are constructed first, and the derived class' members are constructed last. Calling a virtual method from a base class will not work as you expect in Java, since the derived class has not been constructed yet, and thus the virtual methods have not been redirected to the derived implementations yet. Hope that makes sense.

However, calling method() on a SuperClass object after creation will work as you expect: it would call the virtual function which would output "print".

class SuperClass {

public:
    SuperClass() {
        // cannot call virtual functions from base constructor.
    }
    virtual ~SuperClass() { } // destructor. as Kerrek mentions,
                               // classes that will be inherited from,
                               // should always have virtual destructors.
                               // This allows the destructors of derived classes
                               // to be called when the base is destroyed.

private:
    void method() {
        unimplementedMethod();
    }

protected:
    virtual void unimplementedMethod() = 0; // makes method pure virtual,
                                            // to be implemented in subclass
}

SubClass.h

class SubClass : public SuperClass {

public:
    SubClass() : SuperClass() { // how the superclass constructor is called.

    }

    // no need for "override" keyword, if the methd has the same name, it will
    // automatically override that method from the superclass
protected:
    void unimplementedMethod() { 
        std::cout << "print" << std::endl;
    }
}
like image 149
Alexander Kondratskiy Avatar answered Jan 20 '23 00:01

Alexander Kondratskiy