Is the following code the proper usage of shared_from_this - in the context of (multiple inheritance and proper reference counts)? The code is and implementation of the double dispatch visitor pattern where the interface accepts a shared pointer.
class EventIf;
typedef std::shared_ptr<EventIf> EventIfPtr;
class DispatchIF;
typedef std::shared_ptr<DispatchIF> DispatchIFPtr;
class EventOne;
typedef std::shared_ptr<EventOne> EventOnePtr;
class EventTwo;
typedef std::shared_ptr<EventTwo> EventTwoPtr;
class DispatchIF
{
public:
Dispatch(EventOnePtr pEvent){ std::cout << pEvent->GetType(); }
Dispatch(EventTwoPtr pEvent){ std::cout << pEvent->GetType() << pEvent->foo; }
};
class EventIf
{
public:
EventIf(theType) : type(theType) {}
virtual ~EventIf(){}
int GetType(){ return type; }
virtual void Accept(DispatchIFPtr pDispatcher) = 0;
protected:
int type;
};
cass EventOne : public EventIf, std::enable_shared_from_this<EventOne>
{
public:
EventOne() : EventIf(1) {}
virtual ~EventOne(){}
virtual void Accept(DispatchIFPtr pDispatcher){ pDispatcher->Dispatch(shared_from_this()); }
};
cass EventTwo : public EventIf, std::enable_shared_from_this<EventTwo>
{
public:
EventTwo() : EventIf(1) {}
virtual ~EventTwo(){}
virtual void Accept(DispatchIFPtr pDispatcher){ pDispatcher->Dispatch(shared_from_this()); }
public:
int foo;
};
Related
I have several disparate templated pure abstract classes. I derive from these to get a bunch of classes, and from there, I can use those to make a bunch of objects. I would like to put all of these objects into a container. However, they are all of different types. I am wondering how to accomplish this late-stage polymorphism.
Say this is my pre-existing code that I have right now:
#include <iostream>
template<typename T>
class A{
public:
A() : m_num(1.0) {};
virtual ~A() {};
virtual void printNum() const = 0;
protected:
T m_num;
};
template<typename T>
class B{
public:
B() : m_num(2.0) {};
virtual ~B() {};
virtual void printTwiceNum() const = 0;
protected:
T m_num;
};
class A_example : public A<int>
{
public:
A_example() : A<int>() {};
void printNum() const { std::cout << m_num << "\n"; };
};
class B_example : public B<int>
{
public:
B_example() : B<int>() {};
void printTwiceNum() const { std::cout << 2*m_num << "\n"; };
};
int main(){
A_example first;
B_example second;
first.printNum();
second.printTwiceNum();
return 0;
}
With more classes, it could get pretty messy inside of main(). Ideally I could jut iterate over the container and call print() on each element. My first thought is to use a std::vector<unique_ptr<Base>>. This seems to work:
#include <iostream>
#include <vector> // new include
#include <memory> // new include
#include <utility> // new include
// new Base class here
class Base{
public:
virtual ~Base(){};
};
template<typename T>
class A : public Base{ // new inheritance here
public:
A() : m_num(1.0) {};
virtual ~A() {};
virtual void printNum() const = 0;
protected:
T m_num;
};
template<typename T>
class B : public Base{ // new inheritance here as well
public:
B() : m_num(2.0) {};
virtual ~B() {};
virtual void printTwiceNum() const = 0;
protected:
T m_num;
};
class A_example : public A<int>
{
public:
A_example() : A<int>() {};
void printNum() const { std::cout << m_num << "\n"; };
};
class B_example : public B<int>
{
public:
B_example() : B<int>() {};
void printTwiceNum() const { std::cout << 2*m_num << "\n"; };
};
int main(){
std::vector<std::unique_ptr<Base>> v;
v.emplace_back( new A_example() );
v.emplace_back( new B_example() );
//v[0]->printNum(); // nope
//v[1]->printTwiceNum(); // nope
return 0;
}
This is cool because I didn't have to change A_example or B_example, and all I changed in A and B was that I added : public Base. However, I have no idea how to call each elements print*** function. Is there any way to call the printNum() and printTwiceNum() functions, and for them to be automatically recognized?
The simplest approach is to just make a virtual function Base::print and have your derived classes implement it. But that's not always appropriate.
Another approach is to branch on dynamic_cast conversions. The premise there is that some functions are only available on some classes. But this can get hairy especially when using class templates, as you must handle all expected template parameters.
To generalize this, you can use interface classes. Let's say you have lots of different classes but only a small number of print variations. In that case, it may make sense to do this:
class PrintNumInterface {
public:
virtual void printNum() const = 0;
};
class PrintTwiceNumInterface {
public:
virtual void printTwiceNum() const = 0;
};
template<typename T> class A : public Base, public PrintNumInterface { ... };
template<typename T> class B : public Base, public PrintTwiceNumInterface { ... };
And now, no matter how many additional classes or template expansions you have to deal with, you only need to handle these interfaces:
for (auto& p : v)
{
if (PrintNumInterface* iface = dynamic_cast<PrintNumInterface*>(p.get())
iface->printNum();
else if (PrintTwiceNumInterface* iface = dynamic_cast<PrintTwiceNumInterface*>(p.get())
iface->printTwiceNum();
}
Say I've got the following (pseudo-)code:
class base{
public:
virtual void callMe() = 0;
virtual void doRender() = 0;
}
class a : public base{
public:
virtual void callMe(){/*doA*/} override;
}
class b : public base{
public:
virtual void callMe(){/*doB*/} override;
}
class myClass : public base, public a, public b{
public:
virtual void doRender(){
this->a::callMe();
this->b::callMe();
} override;
}
Would there be a way to write this differently? Something like:
class myClass : public base, public a, public b{
public:
virtual void doRender(){
this->allSupers::callMe();
} override;
}
My goal with this would be to have a base class that can be extended to have different "features", all of which have to be executed on doRender.
I know I could of course keep track of these functions by means of a function pointer list in base, in which the subclasses put their own functions when constructed, but I'd like to avoid that. Having to iterate over these functions still gives me at least three lines of code in my final doRender. (Or one long unreadable line.)
I'm open for suggestions using templates.
Depending on you actual problem at hand, you might be able to use the mixin-style. Essentially you can have each class call the next callMe at the end (or begining) of their own callMe. One benefit is that callMe does not need to be a virtual function. Here is a minimal example (online):
#include <iostream>
class base
{
public:
void callMe() {}; // Empty base case
virtual void doRender() = 0;
};
template <class super>
class a : public super
{
public:
void callMe()
{
std::cout << "doA" << '\n';
super::callMe(); // Call the next
};
};
template <class super>
class b : public super
{
public:
void callMe()
{
std::cout << "doB" << '\n';
super::callMe(); // Call the next
};
};
template <class super>
class myClass_t : public super
{
public:
void doRender()
{
super::callMe();
};
};
using myClass = myClass_t<a<b<base> > >; // Defining the order of evaluation;
int main()
{
myClass m;
m.doRender();
}
With variadic template, you may do:
template <typename ... Ts>
class myClassTs : public base, public Ts...
{
public:
virtual void doRender(){
int dummy[] = {0, (Ts::callMe(), void(), 0)...};
static_cast<void>(dummy); // Silent warning for unused variable
} override;
}
using myClass = myClassTs<a, b>;
And in C++17, it would be
template <typename ... Ts>
class myClassTs : public base, public Ts...
{
public:
virtual void doRender(){
(static_cast<void>(Ts::callMe()), ...);
} override;
}
I'm looking for ways to avoid the "call super" code smell. This code smell is present when a subclass is required to invoke the super class's version of a virtual function when re-implementing that function.
class Base
{
public:
virtual void foo(){ ... }
}
class Derived : public Base
{
public:
virtual void foo(){ Base::foo();// required! ... }
}
If inheritance went only a single layer deep, I could use the template method
class Base
{
public:
void foo(){ ... ; foo_impl(); }
protected:
virtual void foo_impl(){}
}
class Derived : public Base
{
protected:
virtual void foo_impl(){ ... }
}
But if I need to subclass Derived, I'm back where I started.
I'm considering a registration approach.
class Base
{
public:
Base()
{
_registerCallback( [this](){ _baseFoo(); } );
}
void foo()
{
for( auto f : _callbacks )
f();
}
protected:
void registerCallback( std::function<void()> f )
{
_callbacks << f;
}
private:
void _baseFoo() { ... }
std::list< std::function<void()> > _callbacks;
}
class Derived : public Base
{
public:
Derived()
{
_registerCallback( [this](){ _derivedFoo(); } );
}
private:
virtual void _derivedFoo(){ ... }
}
Is there a more standard approach? Any problems with or improvements to this approach?
Use of
class Derived : public Base
{
public:
virtual void foo(){ Base::foo();// required! ... }
}
is the best approach IMO. I am not sure why you would consider that "code smell".
The potential for error is higher in the last approach you suggested.
It's easier to detect a missed call to Base::foo().
If all the classed derived from Base need to implement what Base::foo() does, it's better that the common code be in Base::foo(). The derived classes simply need to make the call.
For what it's worth, we use the pattern at my work a lot and it has proven to be robust over 20+ years of usage.
You can continue using template methods all the way down if you introduce new virtual member function on each level and override it on next one:
template <typename> struct tag {};
class Base
{
public:
void foo() { ... ; foo_impl(tag<Base>{}); }
protected:
virtual void foo_impl(tag<Base>) {}
};
class Derived1 : public Base
{
protected:
virtual void foo_impl(tag<Base>) override final { ... ; foo_impl(tag<Derived1>{}); }
virtual void foo_impl(tag<Derived1>) {}
};
class Derived2 : public Derived1
{
protected:
virtual void foo_impl(tag<Derived1>) override final { ... ; foo_impl(tag<Derived2>{}); }
virtual void foo_impl(tag<Derived2>) {}
};
class Derived3 : public Derived2
{
protected:
virtual void foo_impl(tag<Derived2>) override final { ... ; foo_impl(tag<Derived3>{}); }
virtual void foo_impl(tag<Derived3>) {}
};
If you dislike tag dispatch you can just give methods different names instead, perhaps something like foo_impl_N.
I consider all this overengineering.
chris mentioned a primary concern regards childs not calling their parent's corresponding member functions, this gives an idea about fixing that part:
#include <cassert>
class Base {
public:
void foo() {
foo_impl();
assert(base_foo_called && "call base class foo_impl");
}
protected:
virtual void foo_impl() { base_foo_called = true; }
private:
bool base_foo_called = false;
};
class DerivedFine : public Base {
protected:
void foo_impl() override {
Base::foo_impl();
}
};
class DerivedDerivedFine : public DerivedFine {
protected:
void foo_impl() override {
DerivedFine::foo_impl();
}
};
class DerivedDerivedNotFine : public DerivedFine {
protected:
void foo_impl() override {}
};
int main() {
DerivedFine foo;
foo.foo();
DerivedDerivedFine bar;
bar.foo();
DerivedDerivedNotFine baz;
baz.foo(); // this asserts
}
CRTP can solve everything.
For each foo method, you implement an empty non-virtual foo_before() that does nothing in your CRTP helper.
CRTP helper takes a derived and a base. Its virtual void foo() invokes static_cast<Derived*>(this)->foo_before() then Base::foo() then after_foo().
struct Base {
virtual void foo() { std::cout << "foo\n"; }
virtual ~Base() {};
};
template<class D, class B=Base>
struct foo_helper:B {
virtual void foo() {
static_cast<D*>(this)->before_foo();
this->B::foo();
static_cast<D*>(this)->after_foo();
}
private:
void before_foo() {}; void after_foo() {};
};
struct Derived1 : foo_helper<Derived1> {
void before_foo() { std::cout << "before1\n"; }
};
struct Derived2 : foo_helper<Derived2> {
void before_foo() { std::cout << "before2\n"; }
void after_foo() { std::cout << "after2\n"; }
};
struct DoubleDerived : foo_helper<DoubleDerived, Derived2> {
void after_foo() { std::cout << "even more after\n"; }
};
int main() {
std::cout << "---- Derived1\n";
Derived1 d1;
d1.foo();
std::cout << "---- Derived2\n";
Derived2 d2;
d2.foo();
std::cout << "---- DoubleDerived\n";
DoubleDerived dd;
dd.foo();
}
Live example.
Output:
---- Derived1
before1
foo
---- Derived2
before2
foo
after2
---- DoubleDerived
before2
foo
after2
even more after
Here's an idea inspired by this answer
The idea is to use the fact that constructors and destructors of a struct / class provides a sort of "pre/post function calling" mechanism that gets inherited. So instead of doing the pre/post function calls in the virtual method itself, we can use a functor and define the pre/post function call in the constructor / destructor. That way, functors that inherit from the base functor will inherit the pre/post function call.
Code
struct BasePrePostFunctor
{
BasePrePostFunctor()
{
printf("Base pre-func\n");
}
virtual void operator()()
{
printf("Base Main func\n");
}
~BasePrePostFunctor()
{
printf("Base post-func\n");
}
};
struct DerivedPrePostFunctor : BasePrePostFunctor
{
DerivedPrePostFunctor()
{
printf("Derived pre-func\n");
}
void operator()() override
{
printf("Derived main func\n");
}
~DerivedPrePostFunctor()
{
printf("Derived post-func\n");
}
};
class BaseClass
{
public:
virtual void virtual_func()
{
BasePrePostFunctor func;
func();
}
};
class DerivedClass : public BaseClass
{
public:
void virtual_func() override
{
DerivedPrePostFunctor func;
func();
}
};
int main(int argc, char** argv)
{
DerivedClass derived;
derived.virtual_func();
};
Output
Base pre-func
Derived pre-func
Derived main func
Derived post-func
Base post-func
I want to expose only the functions from the Abstract Class that have been overridden (implemented) by the derived Class.
For example: I have an Abstract Class called Sensor that is implemented by various different types of sensors. Some have more capabilities than others, so I don't want all functions to be exposed. Only the ones implemented. In the following example all sensors can produce DataA, but DataB and DataC are sensor specific. Some can produce all three, some 2 and some only DataA.
//Code Example
class Sensor{
public:
virtual DataContainer* getDataA() = 0; //pure virtual
virtual DataContainer* getDataB() {return null_ptr;}; //but this would appear in the derived objects
virtual DataContainer* getDataC() {return null_ptr;};
}
class SensorA : public Sensor {
public:
virtual DataContainer* getDataA(){
//code
}
}
class SensorAB : public Sensor {
public:
virtual DataContainer* getDataA(){
//code
}
virtual DataContainer* getDataB(){
//code
}
}
//main
Sensor* ab = new SensorAB();
ab->getDataB(); //GOOD
ab->getDataC(); // Not possible
Is there any way to achieve this?
You need more deep class hierarchy.
class Sensor...
class SensorA: virtual public Sensor...
class SensorB: virtual public Sensor...
class SensorAB: public SensorA, public SensorB...
Do not forget about virtual keyword.
Example:
class Sensor {
public:
virtual ~Sensor() {}
template<typename T>
bool CanConvert()
{
return dynamic_cast<T*>(this) != nullptr;
}
template<typename T>
T& Convert()
{
return dynamic_cast<T>(*this);
}
};
class SensorA: virtual public Sensor {
public:
virtual void DataA() = 0;
};
class SensorB: virtual public Sensor {
public:
virtual void DataB() = 0;
};
class SensorC: virtual public Sensor {
public:
virtual void DataC() = 0;
};
class SensorAB: public SensorA, public SensorB {
public:
void DataA() override {
std::cout << "SensorAB::DataA()" << std::endl;
}
void DataB() override {
std::cout << "SensorAB::DataB()" << std::endl;
}
};
Than you can use it:
void Func(Sensor& s)
{
if (s.CanConvert<SensorA>()) {
auto &s_a = s.Convert<SensorA>();
s_a.DataA();
}
if (s.CanConvert<SensorB>()) {
auto &s_b = s.Convert<SensorB>();
s_b.DataB();
}
if (s.CanConvert<SensorC>()) {
auto &s_c = s.Convert<SensorC>();
s_c.DataC();
}
}
...
SensorAB s_ab;
Func(s_ab);
Or you can use static polymorphysm. Create base class for every data type: SensorA, SensorB, SensorC. Than compose sensor with desired interface (SensorAB for example):
template <class Derived>
class SensorA
{
public:
void DataA() { static_cast<Derived*>(this)->DataAImpl(); }
};
template <class Derived>
class SensorB
{
public:
void DataB() { static_cast<Derived*>(this)->DataBImpl(); }
};
template <class Derived>
class SensorC
{
public:
void DataC() { static_cast<Derived*>(this)->DataCImpl(); }
};
class SensorAB: public SensorA<SensorAB>, public SensorB<SensorAB>
{
public:
void DataAImpl()
{
std::cout << "SensorAB::DataAImpl()" << std::endl;
}
void DataBImpl()
{
std::cout << "SensorAB::DataBImpl()" << std::endl;
}
};
Than you can use it:
SensorAB s_ab;
s_ab.DataA();
s_ab.DataB();
And you can use power of compilation time type check. But in this case you can cast only to SensorAB if you have base Sensor class, not in SensorA or SensorB.
This code can help to understand, what I want:
class Base
{
public:
void foo()
{
print("Base\n");
Derived::foo(); // smth like that.
}
};
class Derived:public Base
{
public:
void foo()
{
print("Derived\n");
}
}
int main()
{
Derived bar;
bar.foo();
return 0;
}
Any ideas ?
P.S. very bad idea is pass to foo pointer of derived.
You would need the base class to hold some short of a handle of it's derived class like the example below:
template<typename T>
class Base {
T *handle;
protected:
Base(T *_handle) : handle(_handle) {}
public:
void foo() {
std::cout << "Base" << std::endl;
handle->foo();
}
};
class Derived : public Base<Derived> {
public:
Derived() : Base(this) { }
void foo() { std::cout << "Derived" << std::endl; }
};
LIVE DEMO
Adapted from here:
class Derived:public Base
{
public:
void foo()
{
Base::foo();
print("Derived\n");
}
}
int main()
{
Derived bar;
bar.foo();
}
seems to be what you want.
You can declare an abstract method in Base which sub-classes have to override, but you call it although it is abstract. This called Template Method:
class Base
{
public:
void foo() {
print("Base\n");
_foo();
}
private:
virtual void _foo() = 0;
};
class Derived: public Base
{
virtual void _foo() {
print("Derived\n");
};
};
Another alternative would be to make Base a template and pass the Derived type:
template<class D>
class Base
{
public:
void foo() {
print("Base\n");
D::foo();
}
};
class Derived: public Base<Derived>
{
public:
void foo() {
print("Derived\n");
};
};
I would usually go with the first approach as it is easier to grasp and also works with more than one level of inheritance.
Something like
class Derived : public Base
{
public:
void foo()
{
Base::foo();
printf("Derived\n");
}
};
then
int main()
{
Derived bar;
bar.foo();
return 0;
}
OR
int main()
{
Derived bar;
bar.Base::foo();
bar.Derived::foo();
return 0;
}
You are describing static polymorphism, which is solved by CRTP:
template <typename DERIVED>
class Base
{
public:
DERIVED & derived() { return *static_cast<DERIVED *>(this); }
void foo()
{
print("Base\n");
derived().foo();
}
};
class Derived:public Base<Derived>
{
public:
void foo()
{
print("Derived\n");
}
};
You need a virtual function.
#include "windows.h"
#include <iostream>
class Base
{
public:
virtual void foo() const
{
std::cout << "Base\n";
}
};
class Derived : public Base
{
public:
void foo() const
{
Base::foo();
std::cout << "Derived\n";
}
};
void main()
{
Derived d; // call Base::foo on this object
d.foo();
system("pause");
}