call child static function from parent? - c++

Suppose we have the following:
class Parent {
public:
virtual void run() {
for (int i = 0 ; i < bar.size() ; ++it)
cout << i << "\n" ;
};
protected:
static vector<int> foo() {return vector r({1,2,3,4,5});};
static vector<int> bar;
}
vector<int> Parent::bar = Parent::foo();
Now if I create a child class whose run function would be called externally, how can I redefine the foo function to return something else while still using the parent run function?
Edit: Sorry let me add some more information. Suppose the virtual function run() is a lot of code, all of which is essentially the same. The only difference in the parent and child classes is what values I want specified in the vector bar, so it would seem to be a little wasteful to redefine the virtual function in the child class. However, if you redefine Child::bar, and call Child::run(), the Parent::bar is used since it's defined in the parent class. Is there some way to have the line "vector Parent::bar = Parent::foo();" know in the Child class to use "Child::foo();"?

As usual. Override base virtual function in derived class.
class Parent {
public:
virtual bool run() {return bar;};
static bool foo() {return true;};
static bool bar;
};
class Child: public Parent
{
public:
static bool foo() { return false;};
};
You can then still use base version applying Base:: scope resolution:
int main() {
bool bc = Child::foo();
bool bp = Parent::foo();
std::cout << bc << bp;
return 0;
}
http://ideone.com/TdaNQ5

I am not sure what do you exactly want here. However, you can override the static function like this,
class Child: public Parent
{
public:
static bool foo() {return false;};
};

You really don't say much about your problem, therefore it is hard to distinguish what you need from what is potentially an XY problem.
One potential problem with your architecture is that you have a Parent and a Child classes that share a static variable bar yet you seem to initialize them differently for Parent and Child classes. However, there is only one bar that is shared both by Parent and Child objects, independently of who wrote to it last.
So, what do you expect when both a Parent and a Child objects are used simultaneously? The answer you look for depends on your answer on that one. In particular, if your answer is 'it is not designed to have Parent and Child objects operate simultaneously', then both classes should definitely not share a static variable.

Related

What happens when a pure virtual function is called on an instance of the parent class in which it is declared?

I am new to C++ and have run into an interesting problem in some code with which I have been working lately. Suppose we have the following classes: Parent, Child_A, Child_B, and Child_C:
class Parent {
...
virtual int Foo() = 0;
...
}
class Child_A : Parent {
...
int Foo() { return 1; }
...
}
class Child_B : Parent {
...
int Foo() { return 2; }
...
}
class Child_C : Parent {
...
int Foo() { return 3; }
...
}
Now I know what happens if I do this:
std::unique_ptr<Child_A> a = std::make_unique<Child_A>();
Parent *p = &a;
p->Foo();
That will return 1. But my question is, what happens if I do this:
std::unique_ptr<Parent> p = std::make_unique<Parent>();
p->Foo();
Thanks to anyone who can help!
Edit: Turns out that my question does not make any sense, regardless of how many times I try to fix my syntax. A pure virtual function can't be called on the parent like that. I found out later that the code I was looking for did set the parent equal to a member of one of its child classes (with the virtual function defined) before it called that function...I had just missed it before.
You have a little misunderstood about C++ syntax, despite the fact your classes don't inherit from parent class.
When you declare a member function like this void foo() = 0, you are saying that your function isn't implemented and you're making your class abstract, and you cannot instantiate an abstract class. A pure virtual function doesn't mean "return 0".
If you wanted to be able to instantiate a parent, you could make the function virtual (not pure virtual) and then have the children override that function.

Override virtual function with existing function

Let me first say this is a purely academic question, since what I want to do can be better accomplished with multiple layers of inheritance.
That said, I wonder if it's possible to override a virtual function with an existing function without writing a wrapper or adding any inheritance layers. Code:
int myfunc2() { return 2; }
class Parent {
public:
virtual int myfunc() { return 0; }
};
class Child1 : public Parent {
public:
int myfunc() override { return 1; }
};
class Child2 : public Parent {
public:
// There a way to do this?
// int myfunc() = myfunc2;
// instead of this?
int myfunc() { return myfunc2(); };
};
int main() {
Child2 baz;
return baz.myfunc();
}
I'd like to override myfunc in the definition of Child2 by simply "forwarding" the declaration to the existing declaration of myfunc2.
Is this, or something akin to it, possible?
Context: I've got a bunch of child classes, some of which have identical definitions of myfunc, some of which do not. A better solution is to create an intermediate child class that defines the common myfunc and have the pertinent children inherit from that instead.
// There a way to do this?
// int myfunc() = myfunc2;
// instead of this?
int myfunc() { return myfunc2(); };
No, there isn't.
There is a problem.
A non-static member function accepts one more implicit parameter: pointer to the object itself. While a stand-alone function does not have such a parameter, For example you may not use the keyword this or member access syntax inside the definition of a stand alone function.

Namespace Functions within Class alternatives?

I'd like to be able to group similar functions in a class into a group so I don't need to append each name with what it's about.
I've seen this question which says that you can't have namespaces within classes. I've also seen this question which proposes using strongly typed enums. The problem here though, is that I'm not sure whether or not these enums can actually accomodate functions?
The problem contextualised:
class Semaphore
{
public:
void Set(bool State){Semaphore = State;}
bool Get(){return Semaphore;}
void Wait()
{
while (Semaphore)
{
//Wait until the node becomes available.
}
return;
}
private:
bool Semaphore = 0; //Don't operate on the same target simultaneously.
};
class Node : Semaphore
{
public:
unsigned long IP = 0; //IP should be stored in network order.
bool IsNeighbour = 0; //Single hop.
std::vector<int> OpenPorts;
//Rest of code...
};
Currently, NodeClass.Get() is how I can get the semaphore. However this introduces confusion as to what Get() actually gets. I'd like to have something akin to NodeClass.Semaphore::Get(). Otherwise I'd have to have the functions as SemaphoreSet(), SemaphoreGet(), and SemaphoreWait(), which isn't too well organised or nice looking.
I had thought of just having the Semaphore class on it's own, and instantiating it within the other classes, but if I could stick with the inheritance approach, that would be nicer.
So essentially, is it possible to access inherited methods like InheritedClass.Group::Function()?
If you really want to do this, you could force the user to call with the base class name by deleteing the member function in the subclass:
class Base {
public:
void Set(bool) { }
};
class Derived : public Base {
public:
void Set(bool) = delete;
};
int main() {
Derived d;
// d.Set(true); // compiler error
d.Base::Set(true);
}
However, if the semantics of calling Set on the subclass are significantly different than what you'd expect them to be when calling Set on the base class, you should probably use a data member and name a member function accordingly as you've described:
class Base {
public:
void Set(bool) { }
};
class Derived {
public:
void SetBase(bool b) {
b_.Set(b);
}
private:
Base b_;
};
int main() {
Derived d;
d.SetBase(true);
}

Use a derived class automatically

I work on TTY communication with different protocols. I started to implement some code in C++ with classes. A parent class contains some basic functions (write, read...) with some virtual functions. Each protocol is a child class with specific functions. Currently in my application, I'm using directly my child classes, but I want to change the protocol dynamically.
Is it possible in this case to use the parent class as an automatic selector for the child class to choose? And to still use the parent after this selection?
For example (simplified):
class Parent
{
void Write();
void Read();
void AutomaticProtocolSelector();//depending on the response of the device
virtual void function1();
virtual void function2();
};
class protocol1 : public Parent
{
void function1();
};
class protocol2 : public Parent
{
void function2();
};
int main(int argc, char const *argv[])
{
Parent *p;
p->AutomaticProtocolSelector();//let's say protocol1 is selected
p->function1(); //execute the function1 in the child class
...
}
I already read some posts about derived classes and the use of dynamic_cats and static_cast, but it's not exactly what I'm looking for. I'll use this if it's not possible in the way I think.
You seem to be in a kind of bootstrapping problem. You want to use a pointer to Parent to create an implementation of the Parent class. In your program, you are dereferencing a pointer that has not been initialized.
int main(int argc, char const *argv[])
{
Parent *p; // !! Not initialized
p->AutomaticProtocolSelector(); // The application should crash here
p->function1();
// ...
}
Preferably initialize your pointers as nullptr, that might make it more obvious that something fishy is going on.
To let the Parent class provide an implementation of itself, you need a static factory method.
class Parent
{
public:
static std::unique_ptr<Parent> createParent();
void Write();
void Read();
virtual void function1();
virtual void function2();
};
This can then be used in your application as follows:
int main()
{
auto p = Parent::createParent();
p->function1();
p->function2();
// ...
}
However, this also means that in your implementation of Parent, you need to know about some or all possible child classes. This feels a bit backwards, you generally don't want your parent classes to know about their child classes.
As Alexandre Thouvenin also advised, it might be best to move the construction of a child class into a separate factory class.
class ParentFactory
{
public:
ParentFactory() = default;
std::unique_ptr<Parent> createParent() const;
};
In the implementation of the createParent method, you then create an instance of one of the child classes.
Then in your application code, create a factory and use it to get hold of an implementation of the Parent class.
int main()
{
ParentFactory factory;
auto p = factory.createParent();
p->function1();
p->function2();
// ...
}
Note: I used some C++11 features, I hope you don't mind.

Making this code properly polymorphic

I have an abstract class Parent, which has multiple children and blank functions for interacting with each of these children. Each Child overrides Parent's functions and interacts with other Childs in different ways; i.e. Child1 has different implementations for interact_with(Child1), interact_with(Child2), etc etc.
In Parent, I have a function interact_with(Parent foo). Every Child looking to interact with another Child must pass through this function first. Until now everything is good, but then we run into a problem: after some basic logic has been processed, the Child then needs to know the specific type of its parameter so it can go on and call its own overridden function. At the moment I have this:
Child1* child1 = dynamic_cast<Child1*>(foo);
Child2* child2 = dynamic_cast<Child2*>(foo);
Child3* child3 = dynamic_cast<Child3*>(foo);
if(child1 != nullptr){
interact_with(child1)
}
else if(child2 != nullptr){
interact_with(child2)
}
else if(child3 != nullptr){
interact_with(child3)
}
It works, but it isn't a very good solution. It gets especially bad when I have so many classes. Is this indicative of flawed base design, and if so, how would I improve this?
EDIT: To clarify: I have something like this
//Parent is an abstract class
class Parent
{
void interact_with(Parent* foo){
//this is here because there is a lengthy code segment
//that needs to be run no matter what child interacts
//with which
//afterwards, I need to interact with whatever foo really is
}
virtual void interact_with(Child1* child){*blank*};
virtual void interact_with(Child2* child){*blank*};
virtual void interact_with(Child3) child){*blank*};
};
class Child1 : public Parent
{
virtual void interact_with(Child1* child){*do something*};
virtual void interact_with(Child2* child){*do something else*};
virtual void interact_with(Child3* child){*do something else*};
};
Already.
The #imreal answer using double dispatch is correct. However, the dispatches can be done using virtual member functions instead of a map and function pointers (which is actually similar to the vtable the compiler generates).
The problem is that a single virtual function will not solve the problem, because you really need a double dispatch (i.e. a virtual call regarding both objects, not just the one being called).
See the following working example:
#include <iostream>
class Child1;
class Child2;
class Parent
{
public:
virtual void interact_with(Parent* other) = 0;
virtual void interact_with(Child1* child) {};
virtual void interact_with(Child2* child) {};
};
class Child1 : public Parent
{
public:
virtual void interact_with(Parent* other)
{
other->interact_with(this);
}
virtual void interact_with(Child1* child)
{
std::cout << "Child1 - Child1\n";
}
virtual void interact_with(Child2* child)
{
std::cout << "Child1 - Child2\n";
}
};
class Child2 : public Parent
{
public:
virtual void interact_with(Parent* other)
{
other->interact_with(this);
}
virtual void interact_with(Child1* child)
{
std::cout << "Child2 - Child1\n";
}
virtual void interact_with(Child2* child)
{
std::cout << "Child2 - Child2\n";
}
};
int main()
{
Child1 c1;
Parent* p1 = &c1; // upcast to parent, from p1, we don't know the child type
Child2 c2;
Parent* p2 = &c2;
c1.interact_with(&c2); // single virtual call to Child1 - Child2
p1->interact_with(&c2); // single virtual call to Child1 - Child2
p1->interact_with(p2); // double virtual call to Child2 - Child1 (NB: reversed interaction)
}
It outputs:
Child1 - Child2
Child1 - Child2
Child2 - Child1
Note the last one is reversed. That's because to make the dynamic dispatch using virtual functions on the argument, I have to swap the this pointer with the argument. This is fine if these interactions are symmetric. If they aren't, then I'd suggest to create a wrapper around the most generic one swapping the this and the argument again.
Warning: this solution will break your interfaces. But don't worry, they are already broken ;)
In my opinion your design mistake is following: although all children are "equal" you pick one of them to be responsible for interactions and call a method on it (And if you want 3, 4, ..., N equal children (in an array) to interact simultaneously, which one is responsible?)
If in your application all objects are equally important and no object is responsible for interactions, you should move interactions into free overloaded binary functions:
void interact(Child1* a, Child1* b);
void interact(Child1* a, Child2* b);
...
void interact(Child2* a, Child1* b)
{
interact(b, a); // if order does not matter, reuse another function
}
Clearly, it won't solve the problem of boilerplate code, but at least it could help you to re-think your design and to find a better solution than double dispatch or casting.
Also, depending on functions internals, you could probably reduce writing (but not code size) easily by using template functions instead of overloaded ones.
Using dynamic_cast<> like that is bad design like you said. You should make the function interact_with virtual like this in the declaration.
virtual void interact_with(Parent foo);
This will make the method call use the subclass's implementation of interact_with instead of the parent class's. You can then replace everything you've written with just this.
interact_with(foo);
Here is a pretty good explanation of virtual methods.
What you want is double dispatch
There are many approaches that you might take depending on your requirements. A very generic one is having a simple map of the form Key(type, type) -> Value(function) that associates an argument type pair with the function to be called.
In this case you will need a set of free functions of the type void function(Parent*, Parent*) (one for every combination you need) and a map of the type std::unordered_map<std::pair<TypeId, TypeId>, FunctionType> where TypeId is some form of type identifier with value semantics.
Then you do the dispatch at runtime:
if(map_.find(make_pair(type1, type2)) != map_.end())
map_[make_pair(type1, type2)](obj1, obj2);
Not before registering each function:
map_[make_pair(type1, type2)] = func12;
map_[make_pair(type2, type3)] = func23;
....