Как печатать на C ++ - PullRequest
       55

Как печатать на C ++

5 голосов
/ 09 октября 2009

Как смоделировать поведение команды типа C # в C ++?

C # пример:

public static PluginNodeList GetPlugins (Type type)
{
 ...
}

Звоните:

PluginManager.GetPlugins (typeof(IPlugin))

Как реализовать это с помощью C ++? Может быть, библиотеки QT или Boost обеспечивают решение?

Как насчет случая, если вы хотите реализовать .GetPlugins (...) таким образом, чтобы он загружал объекты такого типа из файла (.so или .dll)?

Ответы [ 8 ]

7 голосов
/ 09 октября 2009

Вы можете использовать dynamic_cast для тестирования типов, как показано ниже:

IPlugin* iPluginPtr = NULL;
iPluginPtr = dynamic_cast<IPlugin*>(somePluginPtr);

if (iPluginPtr) {
    // Cast succeeded
} else {
    // Cast failed
}
5 голосов
/ 09 октября 2009

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

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

В производных классах вы можете затем переопределить метод и вернуть этот класс определенного типа. Во время выполнения вы можете, например, вызвать Plugin-> getType (), и он вернет свой конкретный тип. Затем вы можете выполнить static_cast для указателя, чтобы получить правильный указатель производного типа обратно.

Второй способ - использовать typeid для получения класса объекта; но это зависит от компилятора. Вы также можете попробовать привести ваш указатель с помощью dynamic_cast; dynamic_cast возвращает нулевой указатель, когда он приведен к неверному типу; и действительный, когда приводится в правильном типе. Метод динамического приведения имеет большие издержки, чем метод getType, описанный выше.

2 голосов
/ 09 октября 2009

Вы можете использовать typeof () в GCC. С другими компиляторами он либо не поддерживается, либо вам приходится делать сумасшедшие манипуляции с шаблонами, либо использовать «функции ошибок», которые сильно зависят от компилятора (например, как это делает Boost).

2 голосов
/ 09 октября 2009

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

Всегда старайтесь избегать использования dynamic_cast, так как он чаще всего использует сравнение строк, чтобы найти тип объекта, и это делает его действительно медленным.

2 голосов
/ 09 октября 2009

Если вам нужно полное поведение типа typeof, вам придется использовать RTTI (информация о типе времени выполнения) . На многих компиляторах вы должны явно активировать использование RTTI, так как это приводит к накладным расходам во время выполнения.

Затем вы можете использовать typeid или dynamic_cast , чтобы найти тип объекта.

Если вы не хотите использовать typeid, вам придется использовать наследование, указатели и / или перегрузки. Повышение может помочь вам, но это не слишком сложно.

Пример 1:

class Iplugin { ... }

class Plugin1 : public Iplugin { ... }
class Plugin2 : public Iplugin { ... }

void getplugins(Iplugin* p) {
    // ... you don't know the type, but you know
    // what operations it supports via Iplugin
}

void getplugins(Plugin1& p) {
    // expliticly handle Plugin1 objects
}

Как видите, существует несколько способов избежать использования RTTI и typeid.

1 голос
/ 22 марта 2011

Конечно, вы бы просто использовали перегрузку?

static PluginManager::GetPlugins(Type1 &x) {
  // Do something
}

static PluginManager::GetPlugins(Type2 &x) {
  // Do something else
}

, а затем позвоните:

PluginManager::GetPlugins(IPlugin);
1 голос
/ 09 октября 2009

Повышение имеет typeof. C ++ 0x не называет это typeof, но имеет как 'auto', так и 'decltype', которые предоставляют одинаковые функциональные возможности.

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

0 голосов
/ 09 октября 2009

Непосредственно не отвечая на вопрос «как получить typeof () в C ++», но я понимаю из вашего вопроса, что вы смотрите, как создавать плагины в C ++. Если это так, то вас может заинтересовать (еще не) библиотека Boost.Extension и, возможно, ее отражение часть.

...