I know the answer to this question might be simply "No" but I'm hoping that if it is "no" then I'll get a suggestion of doing thing differently.
Consider the following:
class IFoo
{
public:
virtual void Foo() = 0;
};
class IBar : public virtual IFoo
{
public:
virtual void Bar1() = 0;
virtual void Bar2() = 0;
};
template <typename T>
class BaseFoo : public T
{
public:
virtual void Foo() override
{
std::cout << "Common behavior Foo" << std::endl;
}
};
template <typename T>
class BaseBar1 : public T
{
public:
virtual void Bar1() override
{
std::cout << "Common behavior Bar1" << std::endl;
}
};
Now in my class I want to use the base implementation for Foo and only in some conditions use the base implementation of Bar1. So naturally I inherit from BaseFoo1<BaseBar1<IBar>> and in my class's Bar1 I will call the base sometimes (or even all the times if it made sense).
class MyClass : public BaseFoo<BaseBar1<IBar>>
{
public:
void Bar1() override
{
if(SomeCondition())
{
std::cout << "MyClass Bar1" << std::endl;
}
else
{
BaseFoo<BaseBar1<IBar>>::Bar1();
}
}
void Bar2() override {}
bool SomeCondition() { return false;}
};
What I'm interested in, is knowing if there is some way to shorten the call to the base function.
I considered using decltype(this) (or std::decay<decltype(this)>) and then I search for a way to use template metaprogramming to get the base type, but I couldn't find anything useful.
1 - Is there a way to shorten the call to the templated base?
2 - Any comments on the design?
I'm using C++11 in my project, but any suggestion up to C++17 would be nice.
Problem
I want to override a virtual method using an inherited class.
Example
#include <iostream>
class BaseClass
{
public:
void PressButton()
{
Nuke();
}
virtual void Nuke()
{
std::cout << "KABOOM" << std::endl;
}
};
class BigNuke
{
public:
void Nuke()
{
std::cout << "MASSIVE KABOOM" << std::endl;
}
};
class ChildClass : public BaseClass, public BigNuke
{
public:
/*
void Nuke()
{
std::cout << "MASSIVE KABOOM" << std::endl;
}
*/
};
My main looks like this:
BaseClass().PressButton();
ChildClass().PressButton();
The output:
KABOOM
KABOOM
Now I know if my child class does not inherit from BigNuke and I uncomment out that nuke method, I get what I expect:
KABOOM
MASSIVE KABOOM
So how do I get the MASSIVE KABOOM out when inheriting from another class? The only way I see it is for BigNuke to inherit from BaseClass but I don't want this. In my real application I have many different base classes and many different types of big nukes, all of which can be mixed and matched.
What you want to do is "impossible". Their is no such thing in C++ as "linked by name". Basically, your code is equivalent to:
class A {
public:
void f () { g(); }
virtual void g () { }
};
class B {
public:
void h () ;
};
class C: public A, public B { };
And you want to access B::h in A, but A does not know anything about B::h. Changing B::h to B::g won't change anything since these are only names (and there is no such thing as dynamic binding in C++).
One way to do what you want is by overriding C::g and calling B::h in it:
class C {
public:
virtual void g () { B::g(); }
};
If you have many class like B and C, you may want to use a template:
template <typename T>
class _C: public A, public T {
public:
virtual void g () { T::g(); }
};
class C: public _C <B> { };
I am trying to write a c++ abstract class and I can't figure out how to require implementers of this class to contain a static function.
For example:
class AbstractCoolThingDoer
{
void dosomethingcool() = 0; // now if you implement this class
// you better do this
}
class CoolThingDoerUsingAlgorithmA: public AbstractCoolthingDoer
{
void dosomethingcool()
{
//do something cool using Algorithm A
}
}
class CoolThingDoerUsingAlgorithmB: public AbstractCoolthingDoer
{
void dosomethingcool()
{
//do the same thing using Algorithm B
}
}
Now I'd like to do the coolthing without the details of how coolthing gets done. So I'd like to do something like
AbstractCoolThingDoer:dosomethingcool();
without needing to know how the coolthing gets done, but this seems to require a function that is both virtual and static which is of course a contradiction.
The rationale is that CoolThingDoerUsingAlgorithmB may be written later and hopefully the softare that needs cool things done won't have to be rewritten.
EDIT:Not sure I was clear on what I'm trying to accomplish. I have 3 criteria that I'm looking to satisfy
A library that uses abstractcoolthingdoer and does not need to be rewritten ever, even when another coolthingdoer is written that the library has never heard of.
If you try to write a coolthingdoer that doesn't conform to the required structure, then the executable that uses the library won't compile.
coolthingdoer has some static functions that are required.
I'm probably chasing down a poor design, so please point me to a better one. Am I needing a factory?
Maybe, something like this will help (see ideone.com example):
#include <iostream>
class A
{
protected:
virtual void do_thing_impl() = 0;
public:
virtual ~A(){}
static void do_thing(A * _ptr){ _ptr->do_thing_impl(); }
};
class B : public A
{
protected:
void do_thing_impl(){ std::cout << "B impl" << std::endl; }
};
class C : public A
{
protected:
void do_thing_impl(){ std::cout << "C impl" << std::endl; }
};
int main()
{
B b_;
C c_;
A::do_thing(&b_);
A::do_thing(&c_);
return (0);
}
EDIT: It seems to me the OP does not need run-time polymorphism, but rather compile-time polymorphism without need of class instance (use of static functions when the implementation is hidden in the derived classes, no instance required). Hope the code below helps to solve it (example on ideone.com):
#include <iostream>
template <typename Derived>
struct A
{
static void do_thing() { Derived::do_thing(); }
};
struct B : public A<B>
{
friend A<B>;
protected:
static void do_thing() { std::cout << "B impl" << std::endl; }
};
struct C : public A<C>
{
friend A<C>;
protected:
static void do_thing() { std::cout << "C impl" << std::endl; }
};
int main()
{
A<B>::do_thing();
A<C>::do_thing();
return (0);
}
EDIT #2: To force fail at compile-time in case user does not adhere to desired pattern, here is the slight modification at ideone.com:
#include <iostream>
template <typename Derived>
struct A
{
static void do_thing() { Derived::do_thing_impl(); }
};
struct B : public A<B>
{
friend A<B>;
protected:
static void do_thing_impl() { std::cout << "B impl" << std::endl; }
};
struct C : public A<C>
{
friend A<C>;
protected:
static void do_thing_impl() { std::cout << "C impl" << std::endl; }
};
struct D : public A<D>
{
friend A<D>;
};
int main()
{
A<B>::do_thing();
A<C>::do_thing();
A<D>::do_thing(); // This will not compile.
return (0);
}
This looks to me like right place to implement bridge pattern. Maybe this is what you are (unconsciously) willing to achieve. In short you specify an interface and its implementations, then call to your do_thing method in turn calls an implementation on a pointer to implementer class.
C++ example
I have something like that (simplified)
class A
{
public:
virtual void Function () = 0;
};
class B
{
public:
virtual void Function () = 0;
};
class Impl : public A , public B
{
public:
????
};
How can I implement the Function () for A and the Function() for B ?
Visual C++ lets you only define the specific function inline (i.e. not in the cpp file),
but I suppose it's an extension. GCC complains about this.
Is there a standard C++ way to tell the compiler which function I want to override?
(visual c++ 2008)
class Impl : public A , public B
{
public:
void A::Function () { cout << "A::Function" << endl; }
void B::Function () { cout << "B::Function" << endl; }
};
Thank you!
You cannot use qualified names there. I you write void Function() { ... } you are overriding both functions. Herb Sutter shows how it can be solved.
Another option is to rename those functions, because apparently they do something different (otherwise i don't see the problem of overriding both with identical behavior).
I can suggest another way to resolve this issue. You can add wrapper Typed which changes Function signature by adding dummy parameter. Thus you can distinguish methods in your implementation.
class A {
public:
virtual void Function() = 0;
virtual ~A() = default;
};
class B {
public:
virtual void Function() = 0;
virtual ~B() = default;
};
template<typename T>
class Typed : public T {
public:
virtual void Function(T* dummy) = 0;
void Function() override {
Function(nullptr);
}
};
class Impl : public Typed<A>, public Typed<B> {
public:
void Function(A* dummy) override {
std::cerr << "implements A::Function()" << std::endl;
}
void Function(B* dummy) override {
std::cerr << "implements B::Function()" << std::endl;
}
};
The benefit of such solution is that all implementation are placed in one class.
As a workaround, try
struct Impl_A : A
{
void Function () { cout << "A::Function" << endl; }
};
struct Impl_B : B
{
void Function () { cout << "B::function" << endl; }
};
struct Impl : Impl_A, Impl_B {};
If A and B are interfaces, then I would use virtual derivation to "join" them (make them overlap). If you need different implementations for your Function if called through a pointer to A or to B then I would strongly recommend to choose another design. That will hurt otherwise.
Impl "derives from" A and B means Impl "is a" A and B. I suppose you do not mean it.
Impl "implements interface" A and B means Impl "behaves like" A and B. then same interface should mean the same behavior.
In both cases having a different behavior according to the type of pointer used would be "schizophrenic" and is for sure a situation to avoid.
Due to the well-known issues with calling virtual methods from inside constructors and destructors, I commonly end up with classes that need a final-setup method to be called just after their constructor, and a pre-teardown method to be called just before their destructor, like this:
MyObject * obj = new MyObject;
obj->Initialize(); // virtual method call, required after ctor for (obj) to run properly
[...]
obj->AboutToDelete(); // virtual method call, required before dtor for (obj) to clean up properly
delete obj;
This works, but it carries with it the risk that the caller will forget to call either or both of those methods at the appropriate times.
So the question is: Is there any way in C++ to get those methods to be called automatically, so the caller doesn't have to remember to do call them? (I'm guessing there isn't, but I thought I'd ask anyway just in case there is some clever way to do it)
While there is no automated way, you could force the users hand by denying users access to the destructor on that type and declaring a special delete method. In this method you could do the virtual calls you'd like. Creation can take a similar approach which a static factory method.
class MyObject {
...
public:
static MyObject* Create() {
MyObject* pObject = new MyObject();
pObject->Initialize();
return pObject;
}
Delete() {
this->AboutToDelete();
delete this;
}
private:
MyObject() { ... }
virtual ~MyObject() { ... }
};
Now it is not possible to call "delete obj;" unless the call site has access to MyObject private members.
The best I can think of is for you to implement your own smart pointer with a static Create method that news up an instance and calls Initialize, and in its destructor calls AboutToDelete and then delete.
I used a very carefully designed Create() factory method (static member of each class) to call a constructor and initializer pair in the same order as C# initializes types. It returned a shared_ptr to an instance of the type, guaranteeing a heap allocation. It proved reliable and consistent over time.
The trick: I generated my C++ class declarations from XML...
Except for JavedPar's idea for the pre-destruction method, there is no pre-made solution to easily do two-phase construction/destruction in C++. The most obvious way to do this is to follow the Most Common Answer To Problems In C++: "Add another layer of indirection."
You can wrap objects of this class hierarchy within another object. That object's constructors/destructor could then call these methods. Look into Couplien's letter-envelop idiom, for example, or use the smart pointer approach already suggested.
http://www.research.att.com/~bs/wrapper.pdf This paper from Stroustrup will solve your problem.
I tested this under VS 2008 and on UBUNTU against g++ compiler. It worked fine.
#include <iostream>
using namespace std;
template<class T>
class Wrap
{
typedef int (T::*Method)();
T* p;
Method _m;
public:
Wrap(T*pp, Method m): p(pp), _m(m) { (p->*_m)(); }
~Wrap() { delete p; }
};
class X
{
public:
typedef int (*Method)();
virtual int suffix()
{
cout << "X::suffix\n";
return 1;
}
virtual void prefix()
{
cout << "X::prefix\n";
}
X() { cout << "X created\n"; }
virtual ~X() { prefix(); cout << "X destroyed\n"; }
};
class Y : public X
{
public:
Y() : X() { cout << "Y created\n"; }
~Y() { prefix(); cout << "Y destroyed\n"; }
void prefix()
{
cout << "Y::prefix\n";
}
int suffix()
{
cout << "Y::suffix\n";
return 1;
}
};
int main()
{
Wrap<X> xx(new X, &X::suffix);
Wrap<X>yy(new Y, &X::suffix);
}
I was stuck with the same problem, and after a bit of research, I believe there is not any standard solution.
The suggestions that I liked most are the ones provided in the Aleksandrescu et al. book "C++ coding standards" in the item 49.
Quoting them (fair use), you have several options:
Just document it that you need a second method, as you did.
Have another internal state (a boolean) that flags if post-construction has taken place
Use virtual class semantics, in the sense that the constructor of the most-derived class decides which base class to use
Use a factory function.
See his book for details.
You can use static function template in the class. With private ctor/dtor.
Run on vs2015 community
class A {
protected:
A() {}
virtual ~A() {}
virtual void onNew() = 0;
virtual void onDelete() = 0;
public:
void destroy() {
onDelete();
delete this;
}
template <class T> static T* create() {
static_assert(std::is_base_of<A, T>::value, "T must be a descendant of A");
T* t = new T();
t->onNew();
return t;
}
};
class B: public A {
friend A;
protected:
B() {}
virtual ~B() {}
virtual void onNew() override {
}
virtual void onDelete() override {
}
};
int main() {
B* b;
b = A::create<B>();
b->destroy();
}
The main problem with adding post-constructors to C++ is that nobody has yet established how to deal with post-post-constructors, post-post-post-constructors, etc.
The underlying theory is that objects have invariants. This invariant is established by the constructor. Once it has been established, methods of that class can be called. With the introduction of designs that would require post-constructors, you are introducing situations in which class invariants do not become established once the constructor has run. Therefore, it would be equally unsafe to allow calls to virtual functions from post-constructors, and you immediately lose the one apparent benefit they seemed to have.
As your example shows (probably without you realizing), they're not needed:
MyObject * obj = new MyObject;
obj->Initialize(); // virtual method call, required after ctor for (obj) to run properly
obj->AboutToDelete(); // virtual method call, required before dtor for (obj) to clean up properly
delete obj;
Let's show why these methods are not needed. These two calls can invoke virtual functions from MyObject or one of its bases. However, MyObject::MyObject() can safely call those functions too. There is nothing that happens after MyObject::MyObject() returns which would make obj->Initialize() safe. So either obj->Initialize() is wrong or its call can be moved to MyObject::MyObject(). The same logic applies in reverse to obj->AboutToDelete(). The most derived destructor will run first and it can still call all virtual functions, including AboutToDelete().
I had the same problem for construction. This is my solution using C++14.
The idea is to declare an instance of the class Call in the same (or quite close) scope than the declaration of the final object, letting the destructor call the post-creation script.
# include <iostream>
# include <cassert>
# include <memory>
# include <typeinfo>
class A;
// This non-template class stores an access to the instance
// on which a procedure must be called after construction
// The functions are defined after A in order to avoid a loop
class Call
{
protected:
A* a;
public:
Call();
virtual ~Call();
virtual void set(A& a_) = 0;
};
// In this class, the Source must be the final type created
template <typename Source>
class Call_ : public Call
{
static_assert(std::is_final<Source>::value, "");
public:
Call_() : Call() {}
virtual ~Call_() { assert(typeid(*this->a) == typeid(Source)); }
virtual void set(A& a_) { this->a = &a_; }
};
class A
{
protected:
A(Call& call) { std::cout << "Build A" << std::endl; call.set(*this); } // <----
public:
A(A const&) { std::cout << "Copy A" << std::endl; }
virtual ~A() { std::cout << "Delete A" << std::endl; }
virtual void actions_after_construction() = 0; // post-creation procedure
};
Call::Call() : a(nullptr)
{}
Call::~Call()
{
assert(this->a);
this->a->actions_after_construction();
}
class B : public A
{
protected:
B(Call& call) : A(call) { std::cout << "Build B" << std::endl; }
public:
B(B const& b) : A(b) { std::cout << "Copy B" << std::endl; }
virtual ~B() { std::cout << "Delete B" << std::endl; }
virtual void actions_after_construction() { std::cout << "actions by B" << std::endl; }
};
class C final : public B
{
private:
C(Call& call) : B(call) { std::cout << "Build C" << std::endl; }
public:
C(std::shared_ptr<Call> p_call = std::shared_ptr<Call>(new Call_<C>)) : C(*p_call) {}
C(C const& c) : B(c) { std::cout << "Copy C" << std::endl; }
virtual ~C() { std::cout << "Delete C" << std::endl; }
virtual void actions_after_construction() { std::cout << "actions by C" << std::endl; }
};
class D final : public B
{
private:
D(Call& call) : B(call) { std::cout << "Build D" << std::endl; }
public:
D(std::shared_ptr<Call> p_call = std::shared_ptr<Call>(new Call_<D>)) : D(*p_call) {}
D(D const& d) : B(d) { std::cout << "Copy D" << std::endl; }
virtual ~D() { std::cout << "Delete D" << std::endl; }
virtual void actions_after_construction() { std::cout << "actions by D" << std::endl; }
};
int main()
{
{ C c; }
{ D d; }
return 0;
}
Haven't seen the answer yet, but base classes are only one way to add code in a class hierarchy. You can also create classes designed to be added to the other side of the hierarchy:
template<typename Base>
class Derived : public Base {
// You'd need C++0x to solve the forwarding problem correctly.
Derived() : Base() {
Initialize();
}
template<typename T>
Derived(T const& t): Base(t) {
Initialize();
}
//etc
private:
Initialize();
};