Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce static method overloading in child class in C++

I have something like this:

class Base
{
  public:
    static int Lolz()
    {
      return 0;
    }
};

class Child : public Base
{
  public:
    int nothing;
};

template <typename T>
int Produce()
{
  return T::Lolz();
}

and

Produce<Base>();
Produce<Child>();

both return 0, which is of course correct, but unwanted. Is there anyway to enforce the explicit declaration of the Lolz() method in the second class, or maybe throwing an compile-time error when using Produce<Child>()?

Or is it bad OO design and I should do something completely different?

EDIT:

What I am basically trying to do, is to make something like this work:

Manager manager;

manager.RegisterProducer(&Woot::Produce, "Woot");
manager.RegisterProducer(&Goop::Produce, "Goop");

Object obj = manager.Produce("Woot");

or, more generally, an external abstract factory that doesn't know the types of objects it is producing, so that new types can be added without writing more code.

like image 650
GhassanPL Avatar asked Jun 05 '09 19:06

GhassanPL


People also ask

How do you call a static method in child class?

To call a static method from a child class, use the parent keyword inside the child class. Here, the static method can be public or protected .

Can we have same static method in child class?

We can declare static methods with the same signature in the subclass, but it is not considered overriding as there won't be any run-time polymorphism. Hence the answer is 'No'.

Can we overload the static method in subclass?

No, we cannot override static methods because method overriding is based on dynamic binding at runtime and the static methods are bonded using static binding at compile time. So, we cannot override static methods.

Can we override static method c#?

No, they can't be overridden. They are associated with the class, not with an object. for the real use: you can call a static method without the class instance.


1 Answers

There are two ways to avoid it. Actually, it depends on what you want to say.

(1) Making Produce() as an interface of Base class.

template <typename T>
int Produce()
{
  return T::Lolz();
}
class Base
{
    friend int Produce<Base>();

protected:
    static int Lolz()
    {
        return 0;
    }
};

class Child : public Base
{
public:
    int nothing;
};

int main(void)
{
    Produce<Base>(); // Ok.
    Produce<Child>(); // error :'Base::Lolz' : cannot access protected member declared in class 'Base'
}

(2) Using template specialization.

template <typename T>
int Produce()
{
  return T::Lolz();
}
class Base
{
public:
    static int Lolz()
    {
        return 0;
    }
};

class Child : public Base
{
public:
    int nothing;
};

template<>
int Produce<Child>()
{
    throw std::bad_exception("oops!");
    return 0;
}

int main(void)
{
    Produce<Base>(); // Ok.
    Produce<Child>(); // it will throw an exception!
}
like image 101
young Avatar answered Sep 29 '22 09:09

young