Dardan Iljazi
Dardan Iljazi

Reputation: 837

C++/(Qt) pointer to any object with specific method

How do I do to call a specific method present on all classes from an other (TranslationManager) class ? I simplified a lot the code. I just want to call the setTranslationText of any class from TranslationManager.

These are to take in consideration:

  1. All classes have a setTranslationText method
  2. We should call setTranslationText of any class from TranslationManager by using the pointer to the class

    class Interface
    {
       ...
       public:
         void setTranslationText(QString translatedString); 
    }
    
    class AnyOtherInterface
    {
       ...
       public:
         void setTranslationText(QString translatedString); 
    }
    
    ...
    
    …
    Translationmanager::Translationmanager(){
       AnyClass = Interface; // Pointer to Interface Class
       AnyClass->setTranslatioNText("Text");
    
       AnyClass = AnyOtherInterface; // Pointer to AnyOtherInterface Class
       AnyClass->setTranslatioNText("AnotherText");
    }
    
    
    …
    

Upvotes: 0

Views: 173

Answers (3)

Dardan Iljazi
Dardan Iljazi

Reputation: 837

I wasn't precise about what I wanted. I finally found the best solution to my problem: callback.

Solution found on: C++ class member callback simple examples

std::vector<std::function<void(std::string,std::string)>> callbacks;

template<class T> void addTranslationText(T* const object, void(T::* const mf)(std::string,std::string)){
    using namespace std::placeholders;
    callbacks.emplace_back(std::bind(mf, object, _1, _2));
}

...

// Call callback
callbacks.at(0)(std::string("arg1"), std::string("arg2"));

Upvotes: 0

Adding to Cory's answer: If you're using C strings to initialize QString, you shouldn't depend on the implicit conversion - instead, make your use case explicit:

template <typename T>
void setTranslationText(T* t, const char *translatedString) {
  t->setTranslationText(QString::fromUtf8(translatedString));
}

Upvotes: 1

Cory Kramer
Cory Kramer

Reputation: 118011

You could use a template

template <typename T>
void setTranslationText(T* t, const QString &translatedString)
{
    t->setTranslationText(translatedString);
}

That way you wouldn't need an interface class just to inherit for this one (or however many) methods. Then the template would only compile if for a given class instantiation they had a setTranslationText method defined. The way you'd use it is

Translationmanager::Translationmanager()
{
    setTranslationText(Interface, "Text");                // Pointer to Interface Class    
    setTranslationText(AnyOtherInterface, "AnotherText"); // Pointer to AnyOtherInterface Class
}

Upvotes: 5

Related Questions