Как заставить функцию класса вести себя как другая функция класса - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть два класса, ClassWorking и TemplateClass, они никак не связаны.Есть ли способ сказать, я хочу, чтобы функция TemplateGenerate() из моего TemplateClass теперь работала как функция generate() из моего класса ClassWorking.

Как a (эта функция не существует)SetFunctionBehavior(&templateClassRef->templateGenerate, &classWorkingRef->generate)

Я знаю, что могу использовать указатель на функцию, чтобы заставить TemplateClass получить указатель и вызвать его в классе, но это не то, что я хочу.

Это больше похоже на LD_Preload, чтобы заменить внутреннюю часть функции без необходимости переписывать ее и без наследования от класса, у которого она есть.


, чтобы быть немного более явным, давайте рассмотрим это больше как конструкцию узла длякласс

TemplateClass может иметь несколько функций, но не с одинаковым поведением

 - TemplateClass
   - TemplateGenerate() {will do this}
   - TemplateGenerate() {will do that}
   - TemplateGenerate() {will do like that}

, и когда я объявляю свой указатель класса templateClassRef->TemplateGenerate = TemplateGenerate() {will do that}

, но не с лямбда-выражением:)


Смысл в том, чтобы иметь что-то действительно общее без необходимости заново создавать класс для каждой потребности, например, у меня мог бы быть класс:

TemplateGenerate 
 - function A {A1 Behavior}  Functiun B {B1 Behavoir}  Functiun C {C1 Behavior}
              {A2 Behavior}             {B2 Behavoir}             {C2 Behavior}
              {A3 Behavior}             {B3 Behavoir}             {C3 Behavior}

И когдаЯ заявляю о своей функции Я говорю, что беру A1, B2, C3 или A1, B1, C2

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Метод ClassWorking::generate - это функция, которая принимает ClassWorking и делает вещи.

Функция с таким же поведением также принимает ClassWorking. Это часть того, что делает функция.

Поскольку TemplateClass не связан с ClassWorking, метод TemplateClass::templateGenerate, который "ведет себя одинаково" ClassWorking::generate не может быть успешным; у вас нет ClassWorking, поэтому одно из обязательных условий ClassWorking::generate не выполняется.

Теперь может быть так, что реализация ClassWorking::generate на самом деле не нуждается в экземпляре ClassWorking. Возможно, понадобится что-то еще.

Но для того, чтобы компилятор это знал, вам необходимо изменить метод с метода ClassWorking на другой метод. Например, вы можете написать бесплатную функцию generate, которая принимает аргумент, который вам на самом деле нужен, и ClassWorking::generate вызывает эту бесплатную функцию.

Затем вызов свободной функции generate из метода-заглушки TemplateClass::templateGenerate становится тривиальным.

C ++ не поддерживает «делай, что я имею в виду» или «читай мои мысли». Вы на самом деле должны сказать компилятору, что вы хотите, чтобы произошло. И типы имеют значение в C ++, поэтому вы не можете связать метод одного класса с другим классом, не сказав также C ++, как эти типы связаны.

Есть языки, в которых типы являются более свободными, и вы действительно можете извлечь метод из одного класса и приклеить его к другому. Это обычно интерпретируемые языки с гораздо более тяжелыми объектными моделями времени исполнения, чем C ++; члены на этом языке реализованы как пакеты свойств именованных значений, значения на самом деле являются вариантами во время выполнения и т. д.

Вы можете реализовать этот тип объекта в C ++, но это не «нативный» объект C ++, и вам придется написать кучу связующего кода (некоторые из которых могут быть скрыты при метапрограммировании). Это далеко не новичок и обычно плохая идея; если вам нужна гибкость языков сценариев, просто используйте язык сценариев.

0 голосов
/ 04 апреля 2019

Одним из способов является использование композиции .Определите интерфейс

struct Interface
{
    virtual void/*maybe*/ templateGenerate(/*maybe*/) /*const?*/ = 0;
};

Затем реализуйте

struct ClassWorkingImpl : Interface, ClassWorking
{
    // ToDo - delegate all the constructors
    // ToDo - implement templateGenerate using the method in ClassWorking
};

и аналогично для TemplateClass.

Затем создайте экземпляр ClassWorkingImpl & c.а не ClassWorking.И вы можете вызвать интерфейсный метод templateGenerate на любом.

...