C++: Call child static method from parent - c++

Simply, I need to do as the title says: Call a child static method from parent. The problem is that I don't know the child class name in the parent as there could be multiple children. The static method needs to stay static. For example:
class A{ // parent class
public:
void process(){
getData(); // <-- Problem
}
}
class B: public A{ // child class
static int getData();
}
void main(){
B b;
b.process();
}
One solution that comes to mind is to have a virtual method that calls the static method. This would not be very nice and it would mean I would have to implement the method for every child I have:
class A{ // parent class
virtual int getDataFromStaticMethod() = 0;
public:
void process(){
getData(); // <-- Problem
}
}
class B: public A{ // child class
static int getData();
virtual int getDataFromStaticMethod(){
return B::getData();
}
}
void main(){
B b;
b.process();
}
But I really wish it was possible to implement a pure virtual method with a static method:
class A{ // parent class
virtual int getData() = 0;
public:
void process(){
getData(); // <-- Problem
}
}
class B: public A{ // child class
static int getData();
}
void main(){
B b;
b.process();
}
Any suggestions?
Thanks!

You could use templates.
template<typename TChild>
class A
{
typedef TChild child_type;
public:
void process()
{
child_type::getData();
}
};
class B: public A<B>
{
static int getData();
};
class C: public A<C>
{
static int getData();
};
int main(int argc, char** argv)
{
B b;
b.process();
C c;
c.process();
}
Note:
If you want to hold static state in your base class, or if you need to hold a collection of base class objects, then you would need an additional layer:
class ABase
{
//any static state goes here
public:
virtual int process() = 0;
};
template<typename TChild>
class A: public ABase
{
typedef TChild child_type;
public:
int process()
{
child_type::getData();
}
};
class B: public A<B>
{};
std::vector<ABase*> a_list;

Assuming the signature of the child functions are all identical, you could initialize your base class object to hold a pointer to the child's version of the getData() function, e.g.:
class A {
int (*d_getData)();
protected:
explicit A(int (*getData)()): d_getData(getData) {}
public:
void process() {
int data = (this->d_getData)();
// ...
}
};
Obviously, the child classes would need to provide the corresponding constructor argument:
class B: public A {
static int whatever();
public:
B(): A(&whatever) {}
// ...
};
That's sort of an implementation of a per object overridable virtual function.

You can use virtual wrappers around the static function. E.g.
class A{ // parent class
// don't make pure virtual if you don't want to define it in all child classes
virtual int getData() { return 0 };
public:
void process(){
getData();
}
}
class B: public a{ // child class
static int do_getData();
int getData() { return do_getData(); }
}

Related

Remove code duplication for virtual class members in C++ inheritance

I have got myself into a strange issue now. Ill write a really simplified version of the same.
class Base
{
public:
virtual int func1()=0;
virtual int func2()=0;
protected:
int n;
};
class der1: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
};
class der2: public Base
{
// implements the virtual functions of the base and uses the protected data
// members of the base.
}
Now the problem.... both der1 and der2 implements the virtual functions of base pretty much the same way. But some other classes (der3, der4) has their own implementations. But still need to inherit from base.
How do i refactor the code to remove the code duplication in an oop manner?
Here's one solution using an intermediate layer of another abstract base class:
class Base12 : public Base {
protected:
int commonFuncStuffA() {
// Commonly used stuff
}
int commonFuncStuffB() {
}
};
class der1: public Base12
{
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = somethingElse;
}
};
class der2: public Base12
{
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = commonFuncStuffB();
}
};
What I'd do for real production code design looks a bit different though.
Declare an interface for the pure virtual functions
struct IMyInterface {
virtual int func1() = 0;
virtual int func2() = 0;
virtual ~IMyInterface {}
};
Provide a abstract base class with the commonly used data members and functions
class BaseImpl : public IMyInterface {
protected:
int n;
int commonFuncStuffA() {
// Commonly used stuff
}
int commonFuncStuffB() {
// Commonly used stuff
}
};
Provide implementations of the interface in the finally derived classes
class der1: public BaseImpl {
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = somethingElse;
}
};
class der2: public BaseImpl {
public:
virtual int func1() {
n = commonFuncStuffA();
}
virtual int func2() {
n = commonFuncStuffB();
}
};
class der3: public IMyInterface {
public:
virtual int func1() {
// Some completely different implementation of the interface
}
virtual int func2() {
// Some completely different implementation of the interface
}
};
class der4: public IMyInterface {
public:
virtual int func1() {
// Some completely different implementation of the interface
}
virtual int func2() {
// Some completely different implementation of the interface
}
};
Option 1
You may consider using your most common implementation in the Base class. The main feature or drawback of this method is that the base class would no longer be abstract. If this is a problem, go to option 2.
Maybe you can even cope with differences in the derived classes by using the template method pattern to extract the differences in protected virtual functions invoked by the template method.
In anyway, for derived classes that need a completely different appoach, you'd just override the the Base class' method.
class Base
{
public:
virtual int func1();
virtual int func2()=0;
protected:
virtual void f1_specific_part1()=0;
virtual void f1_specific_part2()=0;
int n;
};
int Base::func1() { // common skeleton of the algorithm
...
f1_specific_part1();
...
f1_specific_part2();
...
}
class Der1: public Base
{
protected:
void f1_specific_part1() override; // Implements the specific variation
virtual void f1_specific_part2() override;
};
Option 2
You may consider to factorize the common code of the derived classes into a protected method of the Base class.
The override of the pure virtual function would then just call the base class protected common function (for der1 and der2) or just use their own implementation that is completely different (for der3 and der4).
class Base
{
public:
virtual int func1()=0;
virtual int func2()=0;
protected:
int common_part1_funct1(); // implements some common parts
int common_part2_funct1();
int n;
};
class Der1: public Base
{
...
int func1() override {
common_part1_funct1();
...
common_part2_funct1();
...
}
};
Option 3 ?
Important remark: My answer assumes that there are many commonalities between most of the derived classes. However if you have only a small subset of derived classes that share some commonalities, then the answer of Evg would be would be more appropriate.
The idea with Base12 is:
struct Base {
virtual int func1() = 0;
virtual int func2() = 0;
};
struct Base12 : Base {
protected:
int func12();
};
struct Der1: public Base12 {
virtual int func1() {
return func12();
virtual int func2() {
return func12();
};
struct Der2: public Base12 {
virtual int func1() {
return func12();
virtual int func2() {
return func12();
};

How to get rid of duplicate code in derived classes?

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();
};
};

Will static keyword helps here

class A{
int _a;
public:
/--/ void setfunc(int a) ............. will static works here
{
_a=a;
}
int getValue(){return _a};
};
class B{
public:
void func()
{
/--/ setfunc(1); ...................Dont want to create object of A.
}
};
class C{
public:
void something()
{
A aa;
cout<<aa.getValue(); ............. want a value update by class B setfunc
}
};
int main()
{
B bb;
bb.func();
C cc;
cc.something();
}
Question : How can setfunc() can be called in another function without using that class object. Also, if it changes like setting value of "_a" via someclass B. the same value of will persist whenever I try to retrieve it in someanother class like C via getValue()
In static function you can use only static members of class. Like this (_a is static):
class A {
static int _a;
public:
static void setfunc(int a)
{
_a=a;
}
static int getValue(){return _a};
};
Otherwise, you can't do anything with non-static members:
class A {
int _a;
public:
static void setfunc(int a)
{
_a=a; // Error!
}
static int getValue(){return _a}; // Error!
};

Problematic design modifiying/accessing information of a derived class using the base object

My problem is the following:
int main()
{
Base* derivedobject = new Derived1();
derivedobject->GetProperties()-> ???
return 0;
}
//********************
// BaseClass.h
//********************
struct PropertyStruct
{
int x;
};
class Base
{
public:
Base();
~Base();
virtual PropertyStruct GetProperties() = 0;
private:
};
//********************
// DerivedClass1.h
//********************
struct PropertyStruct
{
int y;
};
class Derived1 : public Base
{
public:
Derived1();
~Derived1();
PropertyStruct GetProperties() { return myOwnDifferentProperties; };
private:
};
//********************
// DerivedClass2.h
//********************
struct PropertyStruct
{
float z;
};
class Derived2 : public Base
{
public:
Derived2();
~Derived2();
PropertyStruct GetProperties() { return myOwnDifferentProperties };
private:
};
If I do it like that I'm going to get an error saying that PropertyStruct is a redefinition. If I use a namespace or rename the struct inside the derived class I am then going to get an error telling me that the return type is not the same as defined by Base.
If I define the virtual functions return type as a pointer it compiles, though the next problem when accessing the function "GetProperties" from the main method (in this example) the base object does not know what variables are inside the struct of the derived class.
Is there any way I can realize this ?
That I can get the different properties of each derived object but using the base class object ?
As others have mentioned, there are ways to achieve your goals here but ultimately you will find yourself writing code like the following:
Base * object = ...;
if object is Derived1 then
get Property1 and do something with it
else if object is Derived2 then
get Property2 and do something with it
This is an anti-pattern in object-oriented programming. You already have a class hierarchy to represent the differences between the various derived types. Rather than extracting the data from your objects and processing it externally, consider adding a virtual function to the base class and letting the derived classes do the processing.
class Base
{
public:
virtual void DoSomething() = 0;
};
class Derived1 : Base
{
public:
void DoSomething()
{
// use myOwnDifferentProperties as necessary
}
private:
PropertyStruct myOwnDifferentProperties;
};
If it's not appropriate to put the required processing in the derived classes (i.e. if it would introduce unwanted responsibilities) then you may want to consider the Visitor Pattern as a way to extend the functionality of your hierarchy.
Since template functions cannot be virtual you can use hierarchy of your properties. It's only one way, no other ways. For get elements of derived Properties you should use virtual getter functions.
struct BaseProp
{
virtual ~BaseProp() { }
virtual boost::any getProperty() const = 0;
};
struct PropertyStruct : BaseProp
{
boost::any getProperty() const { return x; }
private:
int x;
};
struct PropertyStruct2 : BaseProp
{
boost::any getProperty() const { return y; }
private:
float y;
};
class Base
{
public:
virtual std::shared_ptr<BaseProp> GetProperties() const = 0;
virtual ~Base() { }
}
class Derived
{
public:
std::shared_ptr<BaseProp> GetProperties() const { return new PropertyStruct(); }
};
class Derived2
{
public:
std::shared_ptr<BaseProp> GetProperties() const { return new PropertyStruct2(); }
};
You can use template class to do that:
struct PropertyStruct1 {
float f;
};
struct PropertyStruct2 {
int i;
};
template<class T>
class A{
public:
T GetProperties() {return mProps;}
private:
T mProps;
};
int main (int argc, const char * argv[]) {
A<PropertyStruct1> a1;
int f = a1.GetProperties().f;
A<PropertyStruct2> a2;
int i = a2.GetProperties().i;
return 0;
}

C++ Inheritance problem

I have a class as follows:
Class A
{
virtual int doSomethingCool() = 0;
};
Class B : public A
{
int doSomethingCool();
};
Now the problem likes , I have a set of classes whcih are dependent on A as interface. I need to change the prototype of the function for one of the derived classes. i.e. i need to pass it a parameter.
Class C: public A
{
int doSomethingCool(int param);
};
Any suggestions how i can achieve this ?
No, you don't need to add it to the base class.
class A
{
public:
virtual int doSomethingCool() = 0 {}
};
class B : public A
{
public:
int doSomethingCool() {return 0;}
};
class C: public A
{
private:
int doSomethingCool(); // hide base class version!
public:
int doSomethingCool(int param) {return param;}
};
You can still call doSomethingCool() if done through a base class pointer:
C c;
//c.doSomethingCool (); // doesn't work, can't access private member
c.doSomethingCool (42);
A &a = c;
a.doSomethingCool ();
//a.doSomethingCool (42); // doesn't work, no member of A has that signature
Add it to the interface and default it to call the existing method. You don't have to do the default but don't make it pure otherwise all derived classes will have to implement. It might be better to leave it undefined or to throw. Depends on what you want to achieve.
class A
{
public:
virtual int doSomethingCool() = 0;
virtual int doSomethingCool(int param) {doSomethingCool()};
};
Make the function doSomethingCool() take the int parameter in A.
class A
{
public:
virtual void doSomethingCool(int param) = 0;
};
There's no problem. You can do it. The only caveat is that it will not be treated as an override of the base class virtual function.
class A
{
public:
virtual void doSomethingCool() = 0;
};
class B : public A
{
public:
void doSomethingCool();
};
class C: Public A
{
public:
void doSomethingCool(int param);
};
int main(){}
So while technically possible, you may really want to relook at the design of your interface class A.
One option may be to provide a default argument to A::doSomethingCool
virtual void doSomethingCool(int = 0) = 0;
This isn't syntactically correct C++.
No you can't change a prototype. How would it be used? What would be the value of the param if the non-parametric version would be called?
I would have introduced another, more specific, interface:
struct A
{
virtual int doSomethingCool() = 0;
};
struct A_specific : A
{
virtual int doSomethingCoolWithThis(int i) = 0;
};
class ConcreteA : public A
{
int doSomethingCool() { return 0; }
};
class ConcreteA_specific : public A_specific
{
int doSomethingCool() { return 0; }
int doSomethingCoolWithThis(int param) { return param; }
};
Then I would program to the correct interface:
int main()
{
const A& a1 = ConcreteA();
const A_specific& a2 = ConcreteA_specific();
a1.doSomethingCool();
a2.doSomethingCool();
a2.doSomethingCoolWithThis(2);
}
Just to give you another idea ;-)
Good luck!