Расширение класса C++

Ничего себе, я не могу верить, как может, люди не потрудились читать вопрос.

Так или иначе, это - то, что я делаю.

  1. Создают Вас классы "сообщения". Это хранит всю информацию, которой Вы хотите поделиться.
  2. Создают Queue< T> для каждого потока. Используйте SyncLock (блокировка C#) к чтению-записи к нему.
  3. , Когда Вы хотите говорить с потоком, отправьте ему объект сообщения с копия из всей информации, в которой требуется путем добавления сообщения к очереди.
  4. рабочий поток может тогда читать из очереди, читая и обрабатывая каждое сообщение в порядке. Когда нет никаких сообщений, просто не спят.

Удостоверяются, что Вы не совместно используете объекты между двумя потоками. Как только Ваш поток GUI прикрепляет сообщение в Очередь, поток GUI больше не владеет сообщением. Это не может содержать ссылку на сообщение, или Вы вовлечете себя в проблему.

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

ОБНОВЛЕНИЕ: не используйте SyncLock и Очередь. Вместо этого используйте ConcurrentQueue, который обработает любую блокировку автоматически для Вас. Вы получите лучшую производительность и, менее вероятно, сделаете ошибку.

8
задан paul simmons 25 October 2009 в 07:40
поделиться

7 ответов

Нет. C ++ не имеет такой возможности.

Как упоминалось в других ответах, общие обходные пути:

  • Определить производный класс, возможно, с фабрикой, чтобы скрыть фактический класс реализации
  • Определить декоратор класс
  • Определить не Функции-member, которые работают с экземплярами класса
17
ответ дан 3 November 2019 в 13:09
поделиться

Нет, в C ++ это невозможно.

Если вы хотите добиться чего-то подобного, у вас есть 2 варианта,

  • Вы можете наследовать от класса (если это вариант, он может быть незаконным, поскольку класс может быть написан не для разрешения наследования)
  • Вы можете написать свой собственный класс-оболочку с таким же интерфейсом + ваши новые методы и передать его тому, который вы хотите расширить.

Я предпочитаю подход делегирования.

11
ответ дан 3 November 2019 в 13:09
поделиться

Generally not. However, if the library does not create instances of the class that require your extension and you are able to modify all places in the app that create an instance of the class and require your extensions, there is a way you can go:

  • Create a factory function that is called at all places that require an instance of the class and returns a pointer to the instance (google for Design Patterns Factory, ...).
  • Create a derived class with the extensions you want.
  • Make the factory function return your derived class instead of the original class.

Example:


    class derivedClass: public originalClass { /* ... */};

    originalClass* createOriginalClassInstance()
    {
         return new derivedClass();
    }
  • Whenever you need to access the extensions, you need to cast the original cast to the derived class, of course.

This is roughly how to implement the "inherit" method suggested by Glen. Glen's "wrapper class with same interface" method is also very nice from a theoretical point of view, but has slightly different properties that makes it less probable to work in your case.

1
ответ дан 3 November 2019 в 13:09
поделиться

Методы расширения класса C # в основном являются синтаксическим сахаром. Вы получаете ту же функциональность, что и бесплатные функции (т. Е. Функции со ссылкой или постоянной ссылкой на ваш класс в качестве первого параметра). Так как это хорошо работает для STL, почему не для вашего класса?

5
ответ дан 3 November 2019 в 13:09
поделиться

Извините, нет. Как только ваш код находится в obj, вы не можете его изменить. Если это можно сделать в VC, частичные классы уже будут поддерживаться. Однако есть одно исключение: методы операторов могут быть расширены с помощью глобальных функций, подобно тому, как cout << реализован в STL.

-2
ответ дан 3 November 2019 в 13:09
поделиться

Конечно, можно:


template <typename Ext>
class Class: public Ext { /* ... */ };

Это не значит, что это лучший подход.

-3
ответ дан 3 November 2019 в 13:09
поделиться

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

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

Например, std :: find () или std :: sort () являются частью интерфейса std :: vector , даже если они не являются членами класса.

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

1
ответ дан 3 November 2019 в 13:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: