Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a shared pointer of a pure abstract class without using reset and new?

Tags:

c++

In C++ how do I get to use a shared pointer of a pure abstract class without using reset and new?

The example is a little contrived but illustrates the problem I am encountering.

Look at the run() method: reset works but the commented out lines don't...

#include <iostream>
#include <map>
#include <memory>

using namespace std;

class Interf {
public:
    virtual void doSomething()=0;
};


class Foo : public Interf {
public:
    Foo() { cout << "Foo constructed\n"; }

    shared_ptr<Interf> innerInterf;

    void doSomething() {
        cout << "Foo:doSomething()\n";
        innerInterf->doSomething();
    }

    void run() {
        cout << "run() called\n";

        innerInterf.reset(new Bar());                     // this works

        //Bar b;
        //innerInterf = make_shared<Interf>((Interf)b);   // how can i get this to work?
    }

    class Bar : public Interf {
    public:
        Bar() { cout << "Bar constructed\n"; }
        ~Bar(){ cout << "Bar destroyed\n"; }

        void doSomething() { cout << "Bar:doSomething()\n"; }
    };
};

int main() {
    Foo foo;
    foo.run();

    Interf *interf;
    interf = &foo;
    cout << "interf.doSomething()\n";
    interf->doSomething();
}
like image 943
LostLad Avatar asked Jan 18 '21 21:01

LostLad


People also ask

Can we use pointers to abstract class types?

However, you can use pointers and references to abstract class types. You create an abstract class by declaring at least one pure virtual member function. That's a virtual function declared by using the pure specifier (= 0) syntax. Classes derived from the abstract class must implement the pure virtual function or they, too, are abstract classes.

What is an abstract class in Java?

A class that contains at least one pure virtual function is considered an abstract class. Classes derived from the abstract class must implement the pure virtual function or they, too, are abstract classes.

Can an abstract class call a pure virtual function?

If the constructor for an abstract class calls a pure virtual function, either directly or indirectly, the result is undefined. However, constructors and destructors for abstract classes can call other member functions. Pure virtual functions in abstract classes can be defined, or have an implementation.

Why can’t we create objects of abstract classes?

We cannot provide implementation of function draw () in Shape, but we know every derived class must have implementation of draw (). Similarly an Animal class doesn’t have implementation of move () (assuming that all animals move), but all animals must know how to move. We cannot create objects of abstract classes.


2 Answers

Instead of new Bar write make_shared<Bar>, as you are making Bar, not Interf.

Bar b;
innerInterf = make_shared<Bar>(b); // copy constructed? (no idea if that is what you want?)
innerInterf = make_shared<Bar>();  // calls Bar::Bar()

Because I see non-virtual destructors, you might want to research about when to use virtual destructors, and also about rule of 0/3/5, if you haven't already.

Anyway, nice question and good MCVE.

like image 78
KamilCuk Avatar answered Oct 07 '22 13:10

KamilCuk


One of the limitations of an abstract class is that it cannot create its objects directly, instead pointing to subclass objects as base-class Pointers.To facilitate the use of polymorphism, we often need to define virtual functions in the base class.

In many cases, it is unreasonable for the base class itself to generate objects.For example, animal as a base class can be derived from tiger, finch and other subclasses, but the animal itself to generate objects is obviously unreasonable.

In order to solve the above problems, the concept of pure virtual Function is introduced, and the Function is defined as a pure virtual Function(method: virtual returnType Function()= 0;)..To make a derived class non-abstract, the compiler requires that pure virtual functions in the derived class be overloaded to achieve polymorphism.Classes that also contain pure virtual functions are called abstract classes and cannot generate objects.This is a good solution to the above two problems.

For example, in the drawing program, Shape as a base class can derive circles, rectangles, squares, trapezoids, etc. If I want the sum of areas, then I can use an array of Shape *, just call the derived class's area() function in turn.You can't define it as an array without an interface, because it could be a circle, it could be a square, and it could be a rectangle, and so on.

like image 44
Lichard Avatar answered Oct 07 '22 12:10

Lichard