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();
}
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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With