I have an abstract base class, with several concrete derived classes; none of these classes manage any resources.
#include <memory>
#include <vector>
// this is a pure abstract class that contains no resources
class Base {
public:
Base() {};
virtual int doSomething() = 0;
};
class Derived : public Base {
public:
Derived() {};
// this mutates the derived class
int doSomething() override { return 0; };
};
class Derived2 : public Base {
public:
Derived2() {};
// this mutates the derived class
int doSomething() override { return 0; };
};
and I have a function that returns a random derived instance (Derived1, Derived2, Derived3, depending upon a random number throw).
std::unique_ptr<Base> randomDerivedInstance() {
// pick a random number here and return Derived1 or Derived2 etc.
// for the purpose of this problem, I'm just returning a fixed derived class
return std::make_unique<Derived>();
}
and I have a struct that I want to store this derived instance in
struct DataStruct {
// this can contain Derived1 or Derived2
std::unique_ptr<Base> base;
// other things in struct omitted for clarity
// obviously this won't work
DataStruct(std::unique_ptr<Base> base) : base(base) {};
};
I return a unique pointer from my random function, and want to save a copy into the struct, and then call doSomething on it that performs several mutating operations on the class internals, and I don't want them to affect the copy stored in the list.
If I knew the type of the derived instance, I would use a copy constructor to create a new instance and add it to the vector, but in this situation I don't know the specific type of the instance I'm trying to add, so I don't know which specific constructor to use.
int main() {
// I want to create a vector of random instances
std::vector<DataStruct> list;
// I create a random instance
auto myDerived = randomDerivedInstance();
// and I want to push a copy of myDerived before I do something with it
// obviously this doesn't work because its a unique_ptr
// what can I do here?
list.push_back(DataStruct(myDerived));
// do something that mutates myDerived
myDerived->doSomething();
// I don't want my mutations to myDerived to affect the list copy
}
The code above doesn't compile for obvious reasons since I'm trying to assign a unique_ptr in the DataStruct constructor.
What changes do I need to make to this architecture and code in order to get this to work as intended? i.e. add a value-copy of random derived instance to a struct, so that I can mutate the original instance (or vice-versa, add original, and mutate copy).
Thanks for all help in advance!
In class Base add a virtual member function clone:
virtual auto clone() const
-> std::unique_ptr<Base>
= 0;
In each derived class Derived override that to provide a derived class specific clone:
auto clone() const
-> std::unique_ptr<Base>
override
{ return std::unique_ptr<Base>( new Derived{ *this } ); }
It's possible to do this in a more advanced way where if you know the most derived class at compile you can get a clone statically of that type, but it doesn't appear that you need that.
Disclaimer: off-the-cuff code, not reviewed by compiler.
At one time, long ago, a clone function was called a virtual constructor, and that term is used in the FAQ item about this. I think it was introduced by Coplien. The current FAQ text doesn't say.
Also worth noting: in C++11 and later the generation of clone function implementations can be partially automated by Derived inheriting from an implementation that in turn inherits from Base, with forwarding of constructor arguments.
C++03 didn't support forwarding so then one had to use schemes such as code-generating macro (evil but in practice the only real solution back then), implementation inheritance via dominance in a virtual inheritance hierarchy (extremely complex and ugly), or to do the same as we now can do in C++11 and later, but with a Do-It-Yourself argument forwarding scheme (somewhat arbitrary limited).
For an overview of these old C++03 techniques see my 2010 blog article “3 ways to mix in a generic cloning implementation”.
Related
#include <vector>
class Base
{
public:
virtual void foo() = 0;
};
template<typename Bar>
class Cloud : public Base
{
public:
void foo()
{
}
};
class Water
{
};
int main()
{
Cloud<Water> cloud;
std::vector<Base> stuff;
stuff.push_back(cloud);
}
The above shown code fails with the following on MSVC 14.1:
error C2259: 'Base': cannot instantiate abstract class
note: due to following members:
note: 'void Base::foo(void)': is abstract
Why does Base::foo() remain abstract even though Cloud implements it?
How would I implement this in a way that Cloud still derives from Base, overrides foo() and remains templated with typename Bar?
The function is a red herring: std::vector<Base> is a vector of Base objects, hence push_back tries to construct a Base from your Cloud<Water>.
Use a std::vector<std::unique_ptr<Base>> instead.
Templates here are just a distraction - they have nothing to do with your problem.
std::vector<Base> contains Base objects, not references, so if you try to add any derived instance to it, it will try to perform slicing, trying to instantiate a Base from the passed cloud. This, however, besides not being what you probably intended, is not possible, since a straight Base object cannot exist due to Base being an abstract class.
Most probably what you wanted was to push your object in the vector while still keeping the polymorphic behavior. To this end, you have to have a vector of pointers to the base class, and push pointers to the elements - most probably allocated on the heap, and with some mean of handling their lifetime. A simple (albeit possibly not optimal) solution may be having a std::vector<std::shared_ptr<Base>> and push objects allocated with std::make_shared.
Regarding the question "How to publicly inherit from a base class but make some of public methods from the base class private in the derived class?", I have a follow-up question:
I can understand that the C++ standard allows a derived class to relax access restrictions of an inherited method, but I can not think of any legitimate use case where it would make sense to impose access restrictions in the derived class.
From my understanding of the concept of inheritance, if class Derived is public class Base, then anything you can do with Base can also be done with Derived. If one does not want Derived to fulfill the interface of Base, one should not use (public) inheritance in the first place. (Indeed, when I encountered this technique in the wild in ROOT's TH2::Fill(double), is was a clear case of inheritance abuse.)
For virtual methods, access restrictions in Derived are also useless, because any user of Derived can use them by casting a Derived* into a Base*.
So, from my limited C++ newbie point of view, these restrictions are misleading (the programmer of Derived might assume that his virtual now-protected method is not called by anyone else, when in fact it might be) and also confuses [me with regard to] what public inheritance should imply.
Is there some legitimate use case I am missing?
From Herb Sutter, Guru of the Week #18:
Guideline #3: Only if derived classes need to invoke the base implementation of a virtual function, make the virtual function protected.
For detail answer, please read my comment in the code written below:
#include <iostream>
#include <typeinfo>
#include <memory>
struct Ultimate_base {
virtual ~Ultimate_base() {}
void foo() { do_foo(); }
protected:
// Make this method protected, so the derived class of this class
// can invoke this implementation
virtual void do_foo() { std::cout << "Ultimate_base::foo"; }
};
struct Our_derived : Ultimate_base {
private:
// Make this method private, so the derived class of this class
// can't invoke this implementation
void do_foo() {
Ultimate_base::do_foo();
std::cout << " Our_derived::foo";
}
};
struct Derive_from_derive : Our_derived {
private:
void do_foo() {
// You can't call below code
// vvvvvvvvvvvvvvvvvvvvvv
// Our_derived::do_foo();
std::cout << " Derive_from_derive::foo";
}
};
// This class is marked final by making its destructor private
// of course, from C++11, you have new keyword final
struct Derive_with_private_dtor : Ultimate_base {
private:
~Derive_with_private_dtor() {}
};
// You can't have below class because its destructor needs to invoke
// its direct base class destructor
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
/*
struct Derive_from_private_dtor : Derive_with_private_dtor {
};
*/
int main() {
std::unique_ptr<Ultimate_base> p = std::make_unique<Our_derived>();
p->foo();
p = std::make_unique<Derive_from_derive>();
p->foo();
p.reset(new Derive_with_private_dtor);
}
From my understanding of the concept of inheritance, if class Derived is public class Base, then anything you can do with Base can also be done with Derived.
This isn't really the concept of inheritance; this is the concept of polymorphism. In particular, this is a statement of the Liskov Substitution Principle. But inheritance can be used for various things in C++ beyond just polymorphism. In fact, anytime your base class has non-virtual methods or data members, you are using it to inject implementation or state into derived classes, not only for polymorphism. If the base class has no virtual methods and no virtual destructor, then the class shouldn't (can't) be used polymorphically. You may use a base class where neither will the base class ever be instantiated, nor will you ever use a pointer to a base. Here's an example:
template <class T>
struct Foo {
T double_this() { return 2 * static_cast<T&>(*this).data; }
T halve_this() { return 0.5 * static_cast<T&>(*this).data; }
};
What does this weird class do? Well, it can be used to inject some interface into any class with a data member called data (and an appropriate constructor):
struct Bar : Foo<Bar> {
Bar(double x) : data(x) {}
double data;
};
Now Bar has methods double and halve. This pattern is called Curiously Recurring Template Pattern (CRTP). Note that we're never going to instantiate Foo<Bar> or have a pointer to it. We just use the interface it provides, non polymorphically.
Now, suppose someone wants to use Foo, but only wants double in their interface but not halve. In this case, it's completely valid to make halve private in the derived. After all, the derived class is just some particular, non polymorphic type, that does not need to conform to any interface other than what the author wants/documents.
Note that when using CRTP, the base class will typically provide public functions, and you'll typically inherit publicly. The entire advantage of CRTP in this use case is that you can inject interface directly; if you were going to make the methods private or inherit privately you'd be better off make Foo<Bar> a member of Bar instead. So it would be more common to make something public into something private, rather than the reverse, in this particular situation.
I have the following class definitions:
class BaseHandle { /* Lots of things */ };
class VertexHandle : public BaseHandle {
/* Only static members and non-virtual functions, default dtor */ };
class EdgeHandle : public BaseHandle { /* Dito */ };
class FaceHandle : public BaseHandle { /* Dito */ };
All classes have no virtual functions or bases.
The derived classes only derive from BaseHandle and do not add any non-static members, nor non-default dtors.
I want to save Vertex-, Edge- and FaceHandles in the same vector:
std::vector<BaseHandle*> handles;
But it doesn't work, if I retrieve the BaseHandle object and want to dynamic_cast them to the derived object it fails, because the classes are not polymorphic (that's my explanation perhaps I'm wrong).
How could I achieve a common vector of BaseHandles? I should mention, that I can't change the class defintions because they are part of a third party library.
You need to have a virtual destructor in your parent class for it to be used polymorphically
class BaseHandle
{
public:
virtual ~BaseHandle();
...
};
That's because dynamic_cast works with the RTTI (RunTime Type Information) which is only available if your class has at least one virtual member function
And this will also prevent resource leaks, otherwise only the parent class part of your instance would be destroyed
Workaround
You can use an std::vector of std::shared_ptr, not only will you avoid memory leaks by not having to call new and delete by hand but that smart pointer also has a magic property (it stores the deleter to call on destruction based on the way it was constructed) that solves your problem:
int main()
{
std::vector<std::shared_ptr<BaseHandle>> shared_vec;
shared_vec.push_back(std::make_shared<VertexHandle>());
} // At the end of scope all destructors are called correctly
If you don't have access to c++11 you could use boost::shared_ptr
You could store
struct thing
{
enum Type { vertex, edge, face };
Type type;
union
{
VertexHandle * vh;
EdgeHandle * eh;
FaceHandle * fh;
};
};
but it's basically a mess ... are you sure you want to do this? It looks like you are storing multiple types in a single array despite the fact that there is no way to use them polymorphically, so is there actually a good reason to have only one array, and not three?
Following on from a comment by Kerrek. You could "create your own, parallel class hierarchy and add each of those types as a member". For example:
class MyBaseHandle {
public:
virtual ~MyBaseHandle(){}
virtual Box getBoundingBox() const = 0;
};
class MyEdgeHandle : public MyBaseHandle {
std::unique_ptr<EdgeHandle> handle_;
public:
MyHandle(std::unique_ptr<EdgeHandle> handle) : handle_(std::move(handle)) {}
Box getBoundingBox() const override;
};
Then you can dynamic_cast if you want to. But I would try and avoid using dynamic_cast at all. Add virtual methods in your parallel class hierarchy that do what you need. For example I've added a virtual getBoundingBox function to the base class that you can then specialize for your particular kinds of handle:
Box MyEdgeHandle::getBoundingBox() const {
// Get data from EdgeHandle
auto v1 = handle_->getVertex1();
auto v2 = handle_->getVertex2();
// create box from edge data...
return box;
}
Live demo
If all classes derived from BaseHandle only use single-inheritance from BaseHandle (plus maybe inheritance from empty classes with trivial dtor, which are subject to empty-baseclass-optimization) and don't add anything but non-virtual functions and static members, and all derived classes use the default dtor or equivalent, you can just static_cast to the target.
Though be aware that there is no way to know which of the derived classes, if any, it actually was.
I am confused about the concepts of inheritance and polymorphism. I mean, what is the difference between code re-usability and function overriding? Is it impossible to reuse parent class function using inheritance concept or else is it impossible to override parent class variables using Polymorphism. There seems little difference for me.
class A
{
public:
int a;
virtual void get()
{
cout<<"welcome";
}
};
class B:public A
{
a =a+1; //why it is called code reuse
void get() //why it is called overriding
{
cout<<"hi";
}
};
My doubt is about the difference between the code reuse and function overriding.
Lets start with your example.
class A
{
public:
int a;
virtual void get()
{
cout<<"welcome";
}
};
class B:public A
{
a =a+1; //why it is called code reuse
void get() //why it is called overriding
{
cout<<"hi";
}
};
Inheritance: Here you are deriving class B from class A, this means that you can access all of its public variables and method.
a = a + 1
Here you are using variable a of class A, you are reusing the variable a in class B thereby achieving code reusability.
Polymorphism deals with how a program invokes a method depending on the things it has to perform: in your example you are overriding the method get() of class A with method get() of class B. So when you create an instance of Class B and call method get you'll get 'hi' in the console not 'welcome'
Function inheritance allows for abstraction of behaviour from a "more concrete" derived class(es) to a "more abstract" base class. (This is analogous to factoring in basic math and algebra.) In this context, more abstract simply means that less details are specified. It is expected that derived classes will extend (or add to) what is specified in the base class. For example:
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
private:
int m_commonProperty;
};
class Subtype1 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
char getProperty(void) const { return m_specificProperty1; }
private:
char m_specificProperty1;
};
class Subtype2 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
float getProperty(void) const { return m_specificProperty2; }
private:
float m_specificProperty2;
};
Note that in the above example, getCommonProperty() and setCommonProperty(int) are inherited from the CommonBase class, and can be used in instances of objects of type Subtype1 and Subtype2. So we have inheritance here, but we don't really have polymorphism yet (as will be explained below).
You may or may not want to instantiate objects of the base class, but you can still use it to collect/specify behaviour (methods) and properties (fields) that all derived classes will inherit. So with respect to code reuse, if you have more than one type of derived class that shares some common behaviour, you can specify that behaviour only once in the base class and then "reuse" that in all derived classes without having to copy it. For example, in the above code, the specifications of getCommmonProperty() and setCommonProperty(int) can be said to be reused by each Subtype# class because the methods do not need to be rewritten for each.
Polymorphism is related, but it implies more. It basically means that you can treat objects that happen to be from different classes the same way because they all happen to be derived from (extend) a common base class. For this to be really useful, the language should support virtual inheritance. That means that the function signatures can be the same across multiple derived classes (i.e., the signature is part of the common, abstract base class), but will do different things depending on specific type of object.
So modifying the above example to add to CommonBase (but keeping Subtype1 and Subtype2 the same as before):
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
virtual void doSomething(void) = 0;
virtual ~CommonBase() { }
private:
int m_commonProperty;
};
Note that doSomething() is declared here as a pure virtual function in CommonBase (which means that you can never instantiate a CommonBase object directly -- it didn't have to be this way, I just did that to keep things simple). But now, if you have a pointer to a CommonBase object, which can be either a Subtype1 or a Subtype2, you can call doSomething() on it. This will do something different depending on the type of the object. This is polymorphism.
void foo(void)
{
CommonBase * pCB = new Subtype1;
pCB->doSomething();
pCB = new Subtype2;
pCB->doSomething(); // Does something different...
}
In terms of the code sample you provided in the question, the reason get() is called "overriding" is because the behaviour specified in the B::get() version of the method takes precedence over ("overrides") the behaviour specified in the A::get() version of the method if you call get() on an instance of a B object (even if you do it via an A*, because the method was declared virtual in class A).
Finally, your other comment/question about "code reuse" there doesn't quite work as you specified it (since it's not in a method), but I hope it will be clear if you refer to what I wrote above. When you are inheriting behaviour from a common base class and you only have to write the code for that behaviour once (in the base class) and then all derived classes can use it, then that can be considered a type of "code reuse".
You can have parametric polymorphism without inheritance. In C++, this is implemented using templates. Wiki article:
http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29#Parametric_polymorphism
Suppose I have a pure virtual method in the base interface that returns to me a list of something:
class base
{
public:
virtual std::list<something> get() = 0;
};
Suppose I have two classes that inherit the base class:
class A : public base
{
public:
std::list<something> get();
};
class B : public base
{
public:
std::list<something> get();
};
I want that only the A class can return a list<something>, but I need also to have the possibility to get the list using a base pointer, like for example:
base* base_ptr = new A();
base_ptr->get();
What I have to do?
Have I to return a pointer to this list? A reference?
Have I to return a null pointer from the method of class B? Or have I to throw an exception when I try to get the list using a B object? Or have I to change the base class method get, making it not pure and do this work in the base class?
Have I to do something else?
You have nothing else to do. The code you provide does exactly that.
When you get a pointer to the base class, since the method was declared in the base class, and is virtual, the actual implementation will be looked up in the class virtual function table and called appropriately.
So
base* base_ptr = new A();
base_ptr->get();
Will call A::get(). You should not return null from the implementation (well you can't, since null is not convertible to std::list< something > anyway). You have to provide an implementation in A/B since the base class method is declared pure virtual.
EDIT:
you cannot have only A return an std::list< something > and not B since B also inherits the base class, and the base class has a pure virtual method that must be overriden in the derived class. Inheriting from a base class is a "is-a" relationship. The only other way around I could see would be to inherit privately from the class, but that would prevent derived to base conversion.
If you really don't want B to have the get method, don't inherit from base.
Some alternatives are:
Throwing an exception in B::get():
You could throw an exception in B::get() but make sure you explain your rationale well as it is counter-intuitive. IMHO this is pretty bad design, and you risk confusing people using your base class. It is a leaky abstraction and is best avoided.
Separate interface:
You could break base into separate interface for that matter:
class IGetSomething
{
public:
virtual ~IGetSomething() {}
virtual std::list<something> Get() = 0;
};
class base
{
public:
// ...
};
class A : public base, public IGetSomething
{
public:
virtual std::list<something> Get()
{
// Implementation
return std::list<something>();
}
};
class B : public base
{
};
The multiple inheritance in that case is OK because IGetSomething is a pure interface (it does not have member variables or non-pure methods).
EDIT2:
Based on the comments it seems you want to be able to have a common interface between the two classes, yet be able to perform some operation that one implementation do, but the other doesn't provide. It is quite a convoluted scenario but we can take inspiration from COM (don't shoot me yet):
class base
{
public:
virtual ~base() {}
// ... common interface
// TODO: give me a better name
virtual IGetSomething *GetSomething() = 0;
};
class A : public Base
{
public:
virtual IGetSomething *GetSomething()
{
return NULL;
}
};
class B : public Base, public IGetSomething
{
public:
virtual IGetSomething *GetSomething()
{
// Derived-to-base conversion OK
return this;
}
};
Now what you can do is this:
base* base_ptr = new A();
IGetSomething *getSmthing = base_ptr->GetSomething();
if (getSmthing != NULL)
{
std::list<something> listOfSmthing = getSmthing->Get();
}
It is convoluted, but there are several advantages of this method:
You return public interfaces, not concrete implementation classes.
You use inheritance for what it's designed for.
It is hard to use mistakenly: base does not provide std::list get() because it is not a common operation between the concrete implementation.
You are explicit about the semantics of GetSomething(): it allows you to return an interface that can be use to retrieve a list of something.
What about just returning an empty std::list ?
That would be possible but bad design, it's like having a vending machine that can give Coke and Pepsi, except it never serves Pepsi; it's misleading and best avoided.
What about just returning a boost::optional< std::list< something > > ? (as suggested by Andrew)
I think that's a better solution, better than returning and interface that sometimes could be NULL and sometimes not, because then you explicitly know that it's optional, and there would be no mistake about it.
The downside is that it puts boost inside your interface, which I prefer to avoid (it's up to me to use boost, but clients of the interface shouldn't have to be forced to use boost).
return boost::optional in case you need an ability to not return (in B class)
class base
{
public:
virtual boost::optional<std::list<something> > get() = 0;
};
What you are doing is wrong. If it is not common to both the derived classes, you should probably not have it in the base class.
That aside, there is no way to achieve what you want. You have to implement the method in B also - which is precisely the meaning of a pure virtual function. However, you can add a special fail case - such as returning an empty list, or a list with one element containing a predetermined invalid value.