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>
Related
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;
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'm having trouble passing a class DerivedObject (part of class DerivedClass derived from template class BaseClass) derived from BaseObject (part of template class BaseClass) as a template argument to template class BaseClass.
This way, both Base and Derived classes have the access to the object pool, that can contain derived objects. This sounds a bit confusing, so here is the example:
template <class TDerivedClass, class TDerivedObject>
class BaseClass
{
protected:
class BaseObject
{
// Class implementation
}
void foo()
{
static_cast<TDerivedClass*>(this)->foo();
}
std::vector<TDerivedObject*> m_objectPool;
};
The above is the base class implementation.
error C2065: 'DerivedObject' undeclared identifier
The above error is cause by the first line of the class definition bellow:
class DerivedClass : public BaseClass<DerivedClass, DerivedClass::DerivedObject>
{
protected:
class DerivedObject : public BaseObject
{
// Class implementation
}
void foo()
{
// Method implementation
}
};
Is there a way to do this? If not, is there a better solution that would give me the same / similar functionality?
At this point
class DerivedClass : public BaseClass<DerivedClass, DerivedClass::DerivedObject>
The compiler has not seen DerivedClass::DerivedObject so you get an undeclared identifier error. As they type has not been seen you cannot use it as a template parameter. You don't get one for DerivedClass as you already have declared DerivedClass as a class.
You could change you base class and have it store a std::vector<BaseObject*> in it and if you do that then you can change your code to:
template <class TDerivedClass>
class BaseClass
{
protected:
class BaseObject
{
// Class implementation
};
void foo()
{
static_cast<TDerivedClass*>(this)->foo();
}
std::vector<BaseObject*> m_objectPool;
};
class DerivedClass : public BaseClass<DerivedClass>
{
protected:
class DerivedObject : public BaseObject
{
// Class implementation
};
void foo()
{
// Method implementation
}
};
Here is one way of doing something similar to what was requested:
#include <vector>
using std::vector;
template <class TDerivedClass, class TDerivedObject>
class BaseClass
{
public:
class BaseObject
{
// Class implementation
};
protected:
// void foo()
// {
// static_cast<TDerivedClass*>(this)->foo();
// }
// std::vector<TDerivedObject*> m_objectPool;
};
class DerivedClass;
class DerivedObject : public BaseClass<DerivedClass, DerivedObject>::BaseObject
{
// Class implementation
};
class DerivedClass : public BaseClass<DerivedClass, DerivedObject>
{
public:
void foo()
{
// Method implementation
}
};
From your example code, I get the impression that you want to provide different implementations for different base classes. Is there any special reason for using templates? If not, you could use classic polymorphism instead:
class BaseClass
{
class BaseObject {};
virtual ~BaseClass() {} // <- do not forget to provide virtual dtor!
virtual void foo() = 0;
std::vector<BaseObject*> m_objectPool;
};
class DerivedClass : public BaseClass
{
class DerivedObject : public BaseObject {/*...*/};
virtual void foo(){/*...*/}
};
Again, BaseObject would offer virtual or pure virtual functions - as you need.
One thing, however, you lose this way: the guarantee that in the vector there are always the objects of one specific BaseObject sub-type. If this matters for you, you could protect the pool and only allow to add new BaseObjects via DerivedClass. If this is not applicable, I might think up another solution from within BaseClass.
If you do not mind having the DerivedObject structure separately from the DerivedClass you may do something like that:
template <class T>
struct ObjectTypeTrait
{
static_assert(sizeof(T) == 0, "undefined trait");
};
template <class TDerivedClass>
class BaseClass
{
protected:
class BaseObject
{
// Class implementation
};
void foo()
{
static_cast<TDerivedClass*>(this)->foo();
}
std::vector<typename ObjectTypeTrait<TDerivedClass>::obj*> m_objectPool;
};
class DerivedClass;
class DerivedObject
{
// Class implementation
};
template<>
struct ObjectTypeTrait<DerivedClass>
{
using obj = DerivedObject;
};
class DerivedClass : public BaseClass<DerivedClass>
{
protected:
void foo()
{
// Method implementation
}
};
I do not claim this to be very brilliant solution, but you can get the idea - using type traits or typedefs
I'll try to make my intentions clear since there may be more than one approach to this. To start, I have an abstract base class FooBase with a virtual function SayHi(). Foo1 is one of many derived classes.
class FooBase {
public:
virtual void SayHi() = 0;
};
class Foo1 : public FooBase {
public:
virtual void SayHi() {
std::cout<<"Foo1 says Hi\n";
}
};
I also have a Component class and sometimes I would like to implement Foo.. classes as Components. I've used a template class so that any subclass of FooBase can have a Component wrapper.
class FooComponentBase : public Component {
public:
virtual FooBase& GetFoo() = 0;
};
template <class T>
class FooComponent : public FooComponentBase {
private:
T m_foo;
public:
virtual FooBase& GetFoo() {return m_foo;}
};
Now FooComponentBase is an interface to components containing any subclass of FooBase:
void DoTest() {
FooComponentBase* pFooComponent = new FooComponent<Foo1>;
pFooComponent->GetFoo().SayHi(); // "Foo1 says Hi"
delete pFooComponent;
}
So far so good, this works. But it might be neater if FooComponent were inherited from FooBase, so we don't need to go through GetFoo() to access FooBase's methods.
// Inherited version
class FooComponentBase : public Component {};
template <class T>
class FooComponent : public FooComponentBase, public T {};
Unfortunately, FooComponentBase has no access to FooBase even though all of its derived classes do;
void DoTest() {
FooComponentBase* pFooComponent = new FooComponent<Foo1>;
pFooComponent->SayHi(); // Error, FooComponentBase has no SayHi() function
delete pFooComponent;
}
I can't find a way to make this work. It seems like there ought to be a way, maybe using virtual inheritance;
class FooComponentBase : public Component, virtual public FooBase {};
But that won't compile either, since we can't instantiate an abstract class. I hope my intention is clear, I'd like to make FooComponentBase an abstract base class, like FooBase but with Component inheritance, so I can use it to access every flavor of FooComponent.
Is there a neat way to do this?
If you use virtual inheritance in one place, you have to use it everywhere if you want that same base implementation to be used:
class Foo1 : public virtual FooBase {
The other way, which is not as nice but might work out for you, would be to implement all of FooBase's functions in FooComponent:
class FooComponentBase : public Component, public FooBase {
};
template <class T>
class FooComponent : public FooComponentBase {
private:
T m_foo;
public:
void SayHi() {m_foo.SayHi();}
};
Or even:
class FooComponentBase : public Component, public FooBase {
};
template <class T>
class FooComponent : public FooComponentBase, public T {
public:
void SayHi() {T::SayHi();}
};