Is it possible to design a class that will inherit from any one of a group of base classes? I would like to be able to write something like:
class Derived : public ArbitraryBase {
public:
Derived () : ArbitraryBase () {}
...
};
where ArbitraryBase can be some base class determined at compile time. I have a group of base classes that I would like to derive identical classes from. Is there a way to avoid writing an individual derived class for each of the base classes?
If it is truly determined at compile time, you can make your derived class a template:
template<class T>
class Derived : public T {
public:
Derived() {}
...
};
You can later create instantiate this class by providing the base type:
int main() {
Derived< ??? > my_object;
...
}
Where ??? is some compile time way of getting your derived type.
You can do this via a template. Using
template<typename T>
class Derived : public T
{
public:
Derived() : T() {}
// or just use if actually need to provide a default constructor
Derived() = default;
};
gives you a class that inherits from T and calls T's default constructor. You would create a concrete class with it like
Derived<Base1> d;
and now d is a Derived that inherits from Base1.
If you need to inherit from an arbitrary number of bases then you can use a variadic template like
template<typename... Bases>
class Derived : public Bases...
{
public:
Dervied() : Bases()... {}
// or just use if actually need to provide a default constructor
Derived() = default;
};
and it would be used like
Derived<Base1, Base2, ..., BaseN> d;
Related
I would like to assert that a base class is only inherited private.
class Base {
static_assert(...); //check if its derived privat
};
class PublicDerived : public Base {}; //this should fail
class PrivateDerived : private Base {}; //this should work
Is there a way to achieve this?
Base can also be a template class.
My problem was that I don't want that the destructor is called from this base class. For example from delete Base* or unique_ptr<Base>.
A protected destructor solves this issue.
Now the derived classes can use these functionalities the base class provides.
Public inheritation is still possible, but my use case is fullfilled.
class Base {
//...
protected:
constexpr Base() noexcept = default;
~Base() noexcept = default;
};
Suppose we have classes Derived* (here * means distinguishing suffixes), which are derived from class Base. Now a member should be added into class Base, the type of which needs to be differently inherited of its own type in derived classes. It could be represented as following (in logic) in c++:
class Base {
protected:
BaseType m_member;
};
class Derived1 : Base {
DerivedType1 m_member; // this member should be the same member in base class
};
class Derived2 : Base {
DerivedType2 m_member;
};
class BaseType {
protected:
virtual void foo();
};
class DerivedType1 : BaseType { ... };
class DerivedType2 : BaseType { ... };
Here m_member in Derived1 is meant to be exactly m_member in Base, with only types changed (and even the new type is inherited from the old type). I know that this piece of code does not do what I need (here m_members in each class are not related with each other at all), what do I need to do?
I've considered using boost::static_visitor (and without creating new classes for Base) for this case. However, derived classes needs to be classes.
Now my temporary solution for this problem is that derived classes hold this member of the same type as the base classes, but handle this member in different ways. Source:
class Base {
protected:
BaseType m_member;
};
class Derived1 : Base {
public:
Derived1() :
m_member(DerivedType1()) { /* ... */ }
};
So, any better choices? E.g. pointers?
I have a base class which is a template, and two derived classes like below,
template <class parm>
class Base{
};
class Derived1: public Base<Derived1>
{};
class Derived2: public Base<Derived2>
{};
Now I have another class holding a reference to Derived1 object or Derived2 object depending on which is passed into the constructor, but I don't know the syntax, is it achievable in C++?
struct Observer{
// I want to hold a reference to Derived1 or Derived2 based on
// which is passed into the constructor
template <class parm>
Base<parm> & derived_reference;
Observer(Derived1 & d1):derived_reference(d1) // what's the right syntax here?
{}
Observer(Derived2 & d2):derived_reference(d2)
{}
};
// I want to hold a reference to Derived1 or Derived2 based on
// which is passed into the constructor
template <class parm>
Base<parm> & derived_reference;
Given your class structure, that is not possible.
There is no common base class of Base<Derived1> and Base<Derived2>.
You can introduce another class as a base of Base<T> to pull off something that will be usable.
struct RealBase { virtual ~RealBase() {} };
template <class parm>
class Base : public RealBase {};
class Derived1: public Base<Derived1>
{};
class Derived2: public Base<Derived2>
{};
struct Observer{
RealBase& derived_reference;
Observer(Derived1& d1):derived_reference(d1)
{}
Observer(Derived2& d2):derived_reference(d2)
{}
};
That will be useful if you have virtual member functions in RealBase. Otherwise, you'll have to use dynamic_cast in client code for it to be useful.
I have the following class:
class Base {
public:
Base(string name) {
agg = new Aggregate(name);
}
private:
Aggregate* agg;
};
Now I need to extend this class:
class Derived : Base {
public:
Derived(string name) : Base(name) {
agg2 = new Aggregate2(name);
}
private:
Aggregate2* agg2;
};
What I want is when I create a Base object, Aggregate needs to be created and when I create a Derived object only Aggregate2 should be created.
Now this is not happening because Aggregate its created inside the constructor which is called when I create a Derived object and like this Aggregate and Aggregate2 would be created.
I could move the creation to a different method and call that after creating the object.
Is there any other elegant way to do what I want ?
You may use the following:
class Base {
public:
explicit Base(string name) : agg(new Aggregate(name)) {}
protected:
Base() = default;
private:
std::unique_ptr<Aggregate> agg;
};
class Derived : Base {
public:
// implicit call to Base(), you may be explicit if you want
Derived(string name) : agg2(new Aggregate2(name)) {}
private:
std::unique_ptr<Aggregate2> agg2;
};
This is something you shouldn't do. If your second class isn't supposed to have the first Aggregate member, then the right way is to make two separate classes and not to use inheritance:
class Foo1 { ... };
class Foo2 { ... };
Now if you really have a reason to use inheritance you have a few options:
- Use a base class from which both Foo1 and Foo2 will derive. The base class only contains what is common to both Foo1 and Foo2. The Aggregates you need go separately into Foo1 and Foo2. (recommended)
- Let Foo1 have a union member (if you know the whys and wherefores of unions):
union Bla { std::unique_ptr<Agg1> a1; std::unique_ptr<Agg2> a2; };
And I should strongly emphasize that I can hardly think of an example where the second version is meaningful... Go for a separate base class!
Try this code
class Base {
public:
Base() { }
Base(string name) {
agg = new Aggregate(name);
}
void setName(string name) {
agg = new Aggregate(name);
}
private:
Aggregate* agg;
};
class Derived : Base {
public:
Derived(string name) {
agg2 = new Aggregate2(name);
}
private:
Aggregate2* agg2;
};
You can have a string type data member in Base class; which can be assigned value (same as name,in constructor) and you can access it in derived also(make it protected) to initialize agg2 in Derived class.
I would use a constructor overload for this:
class Base {
public:
Base(string name) : agg(new Aggregate(name)) {}
protected:
Base(Aggregate* agg) : agg(agg) {} //Base will take possession of the passed pointer.
private:
std::unique_ptr<Aggregate> agg;
};
class Derived : Base {
public:
Derived(string name) : Base(new Aggregate2(name)) {}
};
Note:
This assumes that Aggregate2 is derived from Aggregate. This assumption is based on the fact that removing ability of a base class in a derived class is at least a very strong code smell. So I concluded that both aggregates basically serve the same function, so that the second variable to hold the Aggregate2 instance is superfluous, and that Aggregate2 is a subclass of Aggregate to match behavior with relation.
I am new to STL. I have written a Template Base class as follows
template <class T>
class Base
{
public:
//Constructor and Destructor ..
Base();
virtual ~Base();
virtual foo() = 0;
};
Now , I want to design my framework such that my inherited classes will be publicly derived from this class and will implement foo in their respective implementations. Problem is that I don't know how to inherit from a Template Base class ?
Is it as below ...
template class<T>
class Derived : public Base<T>
{
// Implementation of Derived constructor etc and methods ...
};
or Normal C++ way
class Derived : public Base
{
};
Any suggestions ? Also, I would appreciate for any information for getting started with STL for newbies like me ...
Regards,
Atul
The later,
class Derived : public Base
will not work, because Base is not a class, it's a class template. Than it depends on whether Derived should be a template or whether it should inherit particular instance of Base:
Template:
template<typename T>
class Derived : public Base<T>
Non-template:
class Derived : public Base<Something>
(where Something is some concrete type like int or char * or std::string)
Either
template class<T>
class Derived : public Base<T>
{ };
if you want Derived to work with Base<>s of any type.
Or
class Derived : public Base<SomeSpecificType>
{ };
if you want Derived to only work with a specific type of Base<>.
Your second example is the way to go.
template class<T>
public Base<T>
{ // Implementation of Base constructor etc and methods ...
};
template class<T>
class Derived : public Base<T>
{ // Implementation of Derived constructor etc and methods ...
public:
Derived() : Base<T>() { } //have to construct the proper instanciation of Base
};
Apart from the above answers, also be aware that it can be in following ways also:
template<typename T>
class Derived : public Base<Something> // Something is some concrete type
or
template<typename T, typename U>
class Derived : public Base<U>