Question

I am trying to write a c++ abstract class and I can't figure out how to require implementers of this class to contain a static function.

For example:

class AbstractCoolThingDoer
{
    void dosomethingcool() = 0; // now if you implement this class 
                                        // you better do this
}

class CoolThingDoerUsingAlgorithmA: public AbstractCoolthingDoer
{
    void dosomethingcool()
    {
        //do something cool using Algorithm A
    }
}

class CoolThingDoerUsingAlgorithmB: public AbstractCoolthingDoer
{
    void dosomethingcool()
    {
        //do the same thing using Algorithm B
    }
}

Now I'd like to do the coolthing without the details of how coolthing gets done. So I'd like to do something like

AbstractCoolThingDoer:dosomethingcool();

without needing to know how the coolthing gets done, but this seems to require a function that is both virtual and static which is of course a contradiction.

The rationale is that CoolThingDoerUsingAlgorithmB may be written later and hopefully the softare that needs cool things done won't have to be rewritten.

EDIT:Not sure I was clear on what I'm trying to accomplish. I have 3 criteria that I'm looking to satisfy

  1. A library that uses abstractcoolthingdoer and does not need to be rewritten ever, even when another coolthingdoer is written that the library has never heard of.

  2. If you try to write a coolthingdoer that doesn't conform to the required structure, then the executable that uses the library won't compile.

  3. coolthingdoer has some static functions that are required.

I'm probably chasing down a poor design, so please point me to a better one. Am I needing a factory?

Was it helpful?

Solution

Maybe, something like this will help (see ideone.com example):

#include <iostream>

class A
{
 protected:
  virtual void do_thing_impl() = 0;
 public:
  virtual ~A(){}
  static void do_thing(A * _ptr){ _ptr->do_thing_impl(); }
};

class B : public A
{
 protected:
  void do_thing_impl(){ std::cout << "B impl" << std::endl; }
};

class C : public A
{
 protected:
  void do_thing_impl(){ std::cout << "C impl" << std::endl; }
};

int main() 
{
 B b_;
 C c_;

 A::do_thing(&b_);
 A::do_thing(&c_);  

 return (0);
}

EDIT: It seems to me the OP does not need run-time polymorphism, but rather compile-time polymorphism without need of class instance (use of static functions when the implementation is hidden in the derived classes, no instance required). Hope the code below helps to solve it (example on ideone.com):

#include <iostream>

template <typename Derived>
struct A
{
  static void do_thing() { Derived::do_thing(); }
};

struct B : public A<B>
{
  friend A<B>;
 protected:
  static void do_thing() { std::cout << "B impl" << std::endl; }
};

struct C : public A<C>
{
  friend A<C>;
 protected:
  static void do_thing() { std::cout << "C impl" << std::endl; }
};

int main() 
{
 A<B>::do_thing();
 A<C>::do_thing();

 return (0);
}

EDIT #2: To force fail at compile-time in case user does not adhere to desired pattern, here is the slight modification at ideone.com:

#include <iostream>

template <typename Derived>
struct A
{
  static void do_thing() { Derived::do_thing_impl(); }
};

struct B : public A<B>
{
  friend A<B>;
 protected:
  static void do_thing_impl() { std::cout << "B impl" << std::endl; }
};

struct C : public A<C>
{
  friend A<C>;
 protected:
  static void do_thing_impl() { std::cout << "C impl" << std::endl; }
};

struct D : public A<D>
{
 friend A<D>;
};

int main() 
{
 A<B>::do_thing();
 A<C>::do_thing();
 A<D>::do_thing(); // This will not compile.

 return (0);
}

OTHER TIPS

This looks to me like right place to implement bridge pattern. Maybe this is what you are (unconsciously) willing to achieve. In short you specify an interface and its implementations, then call to your do_thing method in turn calls an implementation on a pointer to implementer class.

C++ example

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top