Пользовательская функция для экземпляра класса (C ++) - PullRequest
0 голосов
/ 07 июня 2018

У меня есть класс "EngineObject"

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

Сейчас я делаю это с помощью указателей на функции, как это:

class EngineObject{
    public:
    bool (*Update)(EngineObject* Me);
    bool (*Prep)(EngineObject* Me);
    bool (*OnCollide)(EngineObject* Me, EngineObject* Them);
};

Как вы могли заметить, это требует, чтобы я сделал что-то ужасное.Я должен передать объект его функции-члену ... При копании

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

Есть ли какой-нибудь способ, которым я мог бы написать функцию, которую я мог бы применить, для каждого экземпляра объекта, который мог бы получить доступ к частным объектамобъект, и без необходимости передавать объект в функцию?

ДЛЯ ЯСНОСТИ: допустим, я хочу два EngineObjects

EngineObject1 = new EngineObject();
EngineObject2 = new EngineObject();

Я хотел бы установить функцию обновления 1 в (что-то) и 2 - (что-то еще)

EngineObject1.Update = &foo;
EngineObject2.Update = &bar;

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

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

context:

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

По сути, у вас будет класс EngineObjectTemplate, в котором будут указаны все эти функциибудет для этого динамически сгенерированного типа, а затем EngineObject будет создан с использованием функции из класса EngineObjectTemplate

EngineObjectTemplates могут быть созданы во время выполнения путем объединения различных предварительно написанных функций C ++ (Update, Prep, OnCollide),Это будет своего рода «тип».

Если пользователь хочет написать новую функцию update, prep или oncollide, он может написать и скомпилировать его в файл DLL и добавить его в проект.(Который мой EXE-файл будет читать и добавлять в список указателей на функции, на которые могут ссылаться имена строк в языке сценариев для назначения шаблонам и / или, следовательно, объектам двигателя), или они могли создавать сценарии на выбранном мной языке сценариев, которыйконечно, будет медленнее.

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

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Вы можете создать класс вызываемого объекта, который переопределяет () operator.Базовый класс предоставит шаблон для того, что заменяемая функция получает в качестве параметров с дочерними классами, реализующими этот конкретный метод.Затем вы объявляете вызываемый класс как friend вашему классу-владельцу.Подобно следующему:

class EngineObject;
class Callable;

class EngineObject
{
private:
  int member;
  Callable *func;

public:
  EngineObject(int m, Callable *f) : member(m), func(f) {}

  int Call(int p)
  {
    return func(p);
  }

  friend Callable;
};

class Callable;
{
public:
  int operator(EngineObject *eo, int param)
  {
    eo->member = param;
    return param;
  }
};

Выше я также скрыл вызов функции переменной за оболочкой, чтобы внешней функции также не нужно было передавать объект в качестве параметра.

0 голосов
/ 07 июня 2018

То, что вы хотите сделать, невозможно, потому что на самом деле вы спрашиваете:

«Как я могу заставить код жить вне доступа к классу для частных членов».

Если этобыло возможно без прыжков через некоторые уродливые, уродливые обручи, тогда это означало бы, что private сломан.

Единственный способ получить доступ к закрытым членам класса - это то, что класс явно дает вам доступ к ним, либоиз его интерфейса или пометив код как friend как часть его объявления.

Либо члены являются частными, либо нет.Вы не можете иметь это в обоих направлениях.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...