3

I want to design a parent class

//Parent.h
class Parent {
private:
   int currentId;
   static int getIdSquare(); //Just random function for simplicity
}
//Parent.cpp
#include "Parent.h"
int Parent::getIdSquare() { return this->currentId * this->currentId };

Of course this won't work! because you cannot access non-static variable in static function but hold on. I want my child class to be like this

//Child.h
#include "Parent.h"
class Child : public Parent {
private:
    static int index;
};
//Child.cpp
#include "Child.h"
int Child::index = 5;

So that in main when I call Child::getIdSquare(); I will get 25. And I should not be able to call Parent::getIdSquare() because its private. How do I go on about creating something like. This is a non-working code just to illustrate the concept. So if I make another child class i can specified the index in its own body. I want to call the method statically.

Please help me figure out this puzzle!

Cache Staheli
  • 3,510
  • 7
  • 32
  • 51
Zanko
  • 4,298
  • 4
  • 31
  • 54
  • 1
    Is this the same question as your earlier (http://stackoverflow.com/questions/37872126/c-inheritance-with-parent-knowing-the-children)? It's very similar. – Cheers and hth. - Alf Jun 17 '16 at 03:34
  • 1
    How are `Child::index` and `Parent::currentId` related? Should the assignment to index set the value in the currentId value in the parent class? – Jens Jun 17 '16 at 07:48
  • Your problem isn't virtual functions or inheritance, it's a misunderstanding of `static`. `static` functions don't have any concept of `this`. – Roddy Jun 17 '16 at 08:03

2 Answers2

1

It sounds like what you are after is really a virtual static function. Unfortunately, that doesn't exist in C++.

Also, Child::getIdSquare() will also be private, and inaccessible in main().

If you need to statically pass a value from a child class to its parent, you may need to do it during the inheritance itself via a template argument.

template <int id>
class Parent
{
public:
    static int getIdSquare() { return id * id; }
}

class Child : public Parent<5>
{
}

Then Child::getIdSquare() will return 25, as required. It doesn't get around the fact that you want Parent::getIdSquare to be private, while making it public in Child though. For that you would need to declare it as private in Parent and then declare it again as public in Child, with an implementation of return Parent<5>::getIdSquare();

Still not ideal, but it's a relatively vague question, so hard to really find a perfect solution here...

Mitch
  • 1,839
  • 16
  • 23
  • Note that in this case each child has a different parent class, since each template instantiation creates a new type – nsubiron Jun 17 '16 at 03:54
0

I am not sure I completely understand the question, but I see two alternatives. If you want to implement type-specific properties you could go with traits:

template<typename T>
struct Square {};

class Parent {

};

class Child: public Parent {};

template<> Square<Parent> {

};

template<> Square<Child> {
     static constexpr int getIdSquare() {
         return 25;
     }
};

void foo() {
    // this will not compile
    //auto id = Square<Parent>::getIdSquare();

    // but this will
    auto id = Square<Child>::getIdSquare();
}

An alternative design would be to use the template method pattern, but this uses dynamic dispatch. It would look like this:

class Parent {
public:
     int getSquareId() {
         return currentId() * currentId();
     }
private:
     virtual int currentId() = 0;
};

class Child: public Parent {
private:
     virtual int currentId() override {
         return 5;
     }
};
Jens
  • 9,058
  • 2
  • 26
  • 43