Как передать производные классы абстрактного класса в качестве параметра? - PullRequest
1 голос
/ 23 апреля 2020

В настоящее время я работаю над заголовком C ++ для кодирования и декодирования текста. А точнее: UTF-8, UTF-16, UCS-2 и UTF-32. Но я дошел до того, что мои знания C ++ не дадут мне дальнейшего развития:

Я бы хотел использовать абстрактный класс для декодирования и кодирования при создании базовых классов для каждого кода c , Затем, если используется какая-либо функция, связанная с кодированием или декодированием, разработчик должен просто передать в функцию пользовательский тип данных.

Проблема в том, что я понятия не имею, как на самом деле это сделать. , В конце концов, вы не можете передать класс stati c в качестве параметра. Но я тоже не хочу ничего кодировать; Разработчик также должен иметь возможность добавлять любой код c без особых проблем и без изменения моего заголовка.

Кроме того, это должно быть как можно проще. Код будет выглядеть примерно так:

namespace Encoding {

  class Encoder {
  public:
    virtual std::string Encode(std::string sOriginal) = 0;
  };

  // Derived classes like UTF8 and UCS2 here

}

void OutputEncoded(std::string s, Encoder enc) {
  std::cout << enc.Encode(s);
}


int main() {
  OutputEncoded("Hellö Wörld!", Encoding::UTF8);
}

Есть идеи, как это сделать? Может быть, способ без создания объекта, но только с помощью методов stati c? Или я должен использовать объект с указателем?

Ответы [ 2 ]

2 голосов
/ 23 апреля 2020

Возможной альтернативой абстрактному классу является шаблон:

namespace Encoding {

  class UTF8 {
  public:
    static std::string Encode(std::string sOriginal);
  };
  class UCS2 {
  public:
    static std::string Encode(std::string sOriginal);
  };

}

template <typename Encoder>
void OutputEncoded(const std::string& s) {
  std::cout << Encoder::Encode(s);
}

int main()
{
  OutputEncoded<Encoding::UTF8>("Hellö Wörld!");
}

Классы UTF8 и UCS2 должны уважать совместимый / одинаковый интерфейс без принудительного применения, обеспечиваемого абстрактным классом и виртуальным методом.

C + Концепция +20 может помочь обеспечить правильное использование. До SFINAE можно было бы использовать, но более многословно.

1 голос
/ 23 апреля 2020

Я нашел способ сам. Довольно просто, на самом деле.

class Base {
public:
  virtual void DoSomething(void) = 0;
};

class Derived : public Base {
  void DoSomething(void) {
    std::cout << "Test";
  }
} DerivedTest;

Base* const DerivedTestPtr = &DerivedTest;



void Test(Base* b) {
  b->DoSomething();
}



int main() {
  Test(DerivedTestPtr);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...