Say I have a parent class Parent and child classes Child1 and Child2 having the latter implementing MyInterface:
class Parent {
public:
Parent();
virtual ~Parent();
virtual void MyMethod();
}
class MyInterface {
public:
virtual ~MyInterface() {}
virtual void MyInterfaceMethod() = 0;
}
class Child1 : public Parent {
public:
Child1();
virtual ~Child1();
}
class Child2 : public Parent, MyInterface {
public:
Child2();
virtual ~Child2();
virtual void MyInterfaceMethod() override;
}
And say I'm given a Parent* pointer, and I want to check if the object is implementing MyInterface and if yes, cast it to MyInterface*.
I've tried to achieve it this way:
void MyFunction(Parent* p) {
MyInterface* i = dynamic_cast<MyInterface*>(p);
if (i != 0)
DoSomething();
else
cout << "Cannot do anything.";
}
But i always equals to 0 which says it is never casted to the type MyInterface* even if I know for sure that the object has the good type.
How should I achieve this?
Child2 private inherits from MyInterface, unless MyFunction() has the privilege to access the private base subobject, dynamic_cast will always fail.
Since MyInterface seems to be an interface, I think you want public inheritance.
class Child2 : public Parent, public MyInterface { }
// ~~~~~~
LIVE (Other errors fixed)
Your classes must be polymorphic types for dynamic_cast to work.
The simplest way of achieving this is to add
virtual ~Parent() = default;
in the public area of the Parent class. Then the dynamic_cast will sniff around the inheritance tree for your interface like a truffling pig.
Alternatively, instead of using dynamic_cast, we could use the Visitor Pattern:
#include <iostream>
class MyInterface {
public:
virtual void DoSomething() = 0;
};
class Parent {
public:
virtual ~Parent() = default;
virtual void accept(class Visitor& visitor) = 0;
};
class Child1 : public Parent {
public:
virtual void accept(Visitor& visitor);
};
class Child2 : public Parent, public MyInterface {
public:
virtual void accept(Visitor& visitor);
virtual void DoSomething();
};
class Visitor
{
public:
void visit(Child1& child);
void visit(Child2& child);
};
void Child1::accept(Visitor& visitor) { visitor.visit(*this); }
void Child2::accept(Visitor& visitor) { visitor.visit(*this); }
void Child2::DoSomething() { std::cout << "Do something.\n"; }
void Visitor::visit(Child1& child) { std::cout << "Cannot do anything.\n"; }
void Visitor::visit(Child2& child) { child.DoSomething(); }
void MyFunction(Parent& p) {
Visitor v;
p.accept(v);
}
int main()
{
Child1 c1;
Child2 c2;
MyFunction(c1);
MyFunction(c2);
}
Output:
Cannot do anything.
Do something.
Related
I've been trying to find an answer to this question but I couldn't (I don't even know how to properly formulate this) so I decided to write my first post ever on StackOverflow =).
The context is the following:
I have this parent class:
class Parent
{
public:
Parent(){};
void foo(void)
{
//Do some common things
bar();
//Do some more common things
};
protected:
virtual void bar(void) = 0;
};
And I want to create an indefinite amount of derived Childs:
class Child1 : public Parent
{
public:
Child1() : Parent(), child1Variable(0) {};
protected:
virtual void bar(void) = 0;
private:
uint32_t child1Variable;
};
class Child2 : public Parent
{
public:
Child2() : Parent(), child2Variable(0) {};
protected:
virtual void bar(void) = 0;
private:
uint32_t child2Variable;
};
.
.
.
class ChildN : public Parent
{
public:
ChildN() : Parent(), childNVariable(0) {};
protected:
virtual void bar(void) = 0;
private:
uint32_t childNVariable;
};
The reason being mainly not repeating the code in Parent's foo()
Then I would like to create my final instantiable classes as, for instance:
class ExampleFinal : public Child1, public Child3, public Child27
{
//How to define Child1::bar(), Child3::bar() and Child27::bar() ??
private:
void bar(void); //????
};
So the questions are:
How can I define the method for (abusing notation) ExampleFinal::Child1::bar, ExampleFinal::Child3::bar, ...
Am I so stuck on this that I'm overlooking a much simpler solution?
The final goal is being able to do something like:
ExampleFinal test;
test.Child1::foo(); //should end up on "ExampleFinal::Child1::bar"
test.Child3::foo(); //should end up on "ExampleFinal::Child3::bar"
Thanks!
Implementing ExampleFinal::bar() (side-note: bar(void) is a C-ism which has no use in C++) will override all of the bars you have declared at once. If you want to have different versions, you'll need to interpose another layer of classes:
struct GrandChild1 : Child1 {
void bar() override { /*...*/ }
};
// And so on...
struct ExampleFinal : GrandChild1, GrandChild3, GrandChild27 {
// Nothing needed here.
};
Then the behaviour you described will work. Be aware, though, that your inheritance graph means that an ExampleFinal has one Parent subobject per Child. This is not an issue in itself but might not model what you want -- maybe you need virtual inheritance here, but beware of the rabbit hole.
If you want to keep the overrides for all ChildN::bars inside ExampleFinal, you can add tag-dispatching to discern them, at the cost of one more virtual call:
struct Parent {
void foo() {
bar();
};
protected:
template <class Child>
struct tag { };
virtual void bar() = 0;
};
struct Child1 : Parent {
protected:
virtual void bar(tag<Child1>) = 0;
void bar() final override {
return bar(tag<Child1>{});
}
int child1Var;
};
struct Child2 : Parent {
protected:
virtual void bar(tag<Child2>) = 0;
void bar() final override {
return bar(tag<Child2>{});
}
int child2Var;
};
struct ExampleFinal : Child1, Child2 {
protected:
using Parent::tag;
void bar(tag<Child1>) final override {
std::cout << "Child1::bar\n";
}
void bar(tag<Child2>) final override {
std::cout << "Child2::bar\n";
}
};
Note that the bar() to bar(tag<ChildN>) bridge can easily be hidden behind a macro. If you want to avoid the cost of the second virtual call, a CRTP can also be applied here.
I'm currently creating a basic UI system for a game I'm writing. It's organized as a tree of nodes. I'm trying to write it so that only the root node can call the update method on other nodes. I thought I understood C++ inheritance but it's once again laughing at my incompetence. I've tried to create a bare-bones example below:
class Base
{
public:
virtual ~Base() { }
protected:
virtual void update_internal() = 0;
};
class Node_A : public Base
{
protected:
virtual void update_internal() { std::cout << "Update Node A" << std::endl; }
};
class Node_B : public Base
{
protected:
virtual void update_internal() { std::cout << "Update Node B" << std::endl; }
};
class Root : public Base
{
public:
void add_node (Base* node) { m_nodes.push_back(node); }
void update()
{
for (auto& node : m_nodes)
{
node->update_internal();
}
}
protected:
std::vector<Base*> m_nodes;
virtual void update_internal() { }
};
int main()
{
Node_A alpha_node;
Node_B beta_node;
Root root_node;
root_node.add_node(&alpha_node);
root_node.add_node(&beta_node);
root_node.update();
}
When I try to compile this GCC gives me the error:
error: 'virtual void Base::update_internal()' is protected
All of the nodes including root inherit the update_internal() method from Base, I don't understand why it matters that it is protected. I thought it was only private members and methods that derived classes couldn't access.
You can only call a protected/private function of a base class only from an instance of the derived class (unless of course you use friends). So the derived class can only access the private/protected members of its base part, not of some other base. In your case, you call it via a reference to a Base* in
for(auto& node : m_nodes)
node->update_internal();
so the compiler complains.
Just befriend Base and Root;
class Base
{
friend class Root; // <- yes,this
public:
virtual ~Base() { }
protected:
virtual void update_internal() = 0;
};
This is a stock example for the Template Method pattern.
The public method of the Root class exposes, what's needed to be implemented internally.
class Base
{
protected:
virtual void update_internal() = 0;
static void DoUpdate( Base *node )
{
node->update_internal();
}
};
class Root : public Base
{
public:
void update()
{
for (auto node : m_nodes)
{
Base::DoUpdate( node );
}
}
protected:
virtual void update_internal() override {}
std::vector<Base*> m_nodes;
};
I have a class hierarchy like:
class A {
list<A*> children;
public:
void update() {
do_something();
update_current();
for(auto child : children)
children->update();
}
protected:
virtual void update_current() {};
};
class B : public A {
protected:
void update_current() override {
do_something_important();
};
};
class C1 : public B {
protected:
void update_current() override {
B::update_current();
do_something_very_important();
};
};
class C2 : public B {
protected:
void update_current() override {
B::update_current();
do_something_very_important_2();
};
};
int main() {
A* a = new A();
//fill a's childred list somehow
while(come_condition) {
//some code
a.update();
//something else
}
return 0;
}
The question is: how can I remove duplicate B::update_current(); calls from derived classes without changing program's behaviour? Is it possible or are there no solutions except calling base class functions manually? Thank you.
You could make B's children override a different function:
class B : public A {
protected:
void update_current() override final {
do_something_important();
do_something_important_later();
};
virtual void do_something_important_later() = 0;
};
With:
class C2 : public B {
protected:
void do_something_important_later() override {
do_something_very_important_2();
};
};
Is it possible to have a derived class to have two sets of the same virtual functions as the base class? I'm looking to do something like the following. The idea being able to choose between two sets of function pointers.
class Base
{
virtual void func1;
virtual void func2;
};
class Derived: Base
{
float somemember;
void somefunction()
{
Base* func = this->derived_functions1;
}
class derived_functions1
{
virtual void func1()
{
return somemember*100;
}
virtual void func2;
};
class derived_functions2
{
virtual void func1;
virtual void func2;
};
};
class Base
{
public:
virtual void func1();
virtual ~Base(){}
};
struct Impl1 : Base
{
void func1() override {}
};
struct Impl2 : Base
{
void func1() override {}
};
struct Derived : Base
{
Derived(std::unique_ptr<Base> implementation) :
impl(std::move(implementation))
{}
void func1() override { impl->func1(); }
void changeImpl(std::unique_ptr<Base> implementation)
{
impl = std::move(implementation);
}
private:
std::unique_ptr<Base> impl;
};
Not the way you did. But you can make both the inner class derived_functionsX to be themseves public: Base, than have your main Derived to contain a std::unique_ptr<Base> ptryou can set to new derived_functions1 or new derived_functions2
and implement in Derived func1 and func2 to call ptr->func1() and ptr->func2().
For all that to work properly, Base must also have a virtual ~Base() {} otherwise no proper deletion can be done.
In this example, it won't compile, since derived_function1 and derived_functions2 aren't inheriting from Base.
But you could have something like this:
class Base
{
virtual void func1();
virtual void func2();
};
class Wrapper {
public:
Wrapper(int arg)
{
switch(arg)
{
case 1:
b = new derived_functions1;
break;
case 2:
b = new derived_functions2;
break;
default:
cout << "bad value of arg" << arg << endl;
exit(1);
}
}
~Wrapper()
{
delete b;
}
Base* GetClass()
{
return b;
}
private:
Base *b;
class derived_functions1: public Base
{
virtual void func1();
virtual void func2();
};
class derived_functions2: public Base
{
virtual void func1();
virtual void func2();
};
};
Short answer: No. A class can override inherited virtual functions only once.
However, there is a design pattern that exchanges function's behavior on the fly, called Strategy Pattern. In short: the class that has exchangeable behavior has a pointer to a Strategy base class that defines the interface for that behavior. It is populated with concrete Strategy classes. The function that has different behavior just delegates its calls to the Strategy pointer. Here's an example, tailored to your question:
class Base {
public:
virtual void func1() = 0;
virtual void func2() = 0;
virtual ~Base(){}
};
#include <iostream>
#include <memory>
class Derived : public Base
{
struct F1Strategy {
virtual void f1Impl() = 0;
virtual ~F1Strategy() {}
};
struct Impl1 : F1Strategy {
void f1Impl() override { std::cout << "one!\n"; }
};
struct Impl2 : F1Strategy {
void f1Impl() override { std::cout << "two?\n"; }
};
std::unique_ptr<F1Strategy> f1Strategy;
public:
Derived()
: f1Strategy(new Impl1())
{}
void func1() override { f1Strategy->f1Impl(); }
void func2() override {
static std::unique_ptr<F1Strategy> otherStrategy(new Impl2());
f1Strategy.swap(otherStrategy);
}
};
int main() {
std::unique_ptr<Base> pb(new Derived());
pb->func1(); // ==> one!
pb->func2(); //swap
pb->func1(); // ==> two?
pb->func1(); // ==> two?
pb->func2(); //swap
pb->func1(); // ==> one!
}
See it in action: http://ideone.com/zk3UTI
I can't figure out how to call a base class method from a derived class method but concurrently applying this method call at an object passed as argument.
What I mean is this:
class Animal
{
virtual void eat(Animal& to_be_eaten) = 0;
};
class Carnivores: public Animal
{
virtual void eat(Animal& to_be_eaten) { /*implementation here*/}
};
class Wolf : public Carnivores
{
virtual void eat(Animal& to_be_eaten)
{ /*call eat method(of Base class) of Base to_be_eaten here*/ }
}
I thought of something like this
dynamic_cast<Carnivores&>(to_be_eaten).eat(*this) //and got a segmentation fault
Is there any way for this to be done?
Thank you!
New edit::
Updated the code
As simple as:
class Derived : public Base {
virtual void eat(Animal& to_be_eaten) {
Base::eat(to_be_eaten);
// do anything you want with to_be_eaten here.
}
};
EDIT: This works for me:
class Animal
{
virtual void eat(Animal& to_be_eaten) = 0;
};
class Carnivores: public Animal
{
virtual void eat(Animal& to_be_eaten) { /*implementation here*/}
};
class Wolf : public Carnivores
{
virtual void eat(Animal& to_be_eaten)
{
Carnivores *c = dynamic_cast<Carnivores*>(&to_be_eaten);
if(c)
c->Carnivores::eat(*this);
}
}
Note that i had to make Base::eat public in order to call it from Derived.
If I understand correctly, what you want is not to use a virtual call on the parameter object (to_be_eaten). I think only an object can do that for himself. I don't think there's a way for other objects to do it for him.
class Base
{
public:
virtual eat(Base& to_be_eaten);
protected:
virtual callEatNonVirtual(Base& other) = 0;
};
class Derived1 : public Base
{
public:
virtual eat(Base& to_be_eaten)
{
to_be_eaten.callEatNonVirtual(*this);
}
protected:
virtual callEatNonVirtual(Base& other)
{
Base::eat(other);
}
};
class Derived2 : public Base
{
public:
virtual eat(Base& to_be_eaten)
{
to_be_eaten.callEatNonVirtual(*this);
}
protected:
virtual callEatNonVirtual(Base& other)
{
Base::eat(other);
}
};