Когда мне нужен анонимный класс на С++?
В С++ есть функция, называемая анонимным классом. Это похоже на анонимную структуру в C. Я думаю, что эта функция придумана из-за некоторых потребностей, но я не могу понять, что это такое.
Могу ли я получить пример, который действительно нуждается в анонимном классе?
Ответы
Ответ 1
Эта функция существует, потому что struct
и class
- одно и то же - все, что вы можете сделать с одним, вы можете сделать с другим. Он служит точно такой же цели, как анонимный struct
в C; когда вы хотите сгруппировать некоторые вещи вместе и объявить один или несколько экземпляров, но не нужно ссылаться на этот тип по имени.
Он менее часто используется в С++, отчасти потому, что проекты С++ имеют тенденцию быть более ориентированными на тип, а отчасти потому, что вы не можете объявлять конструкторы или деструкторы для анонимных классов.
Ответ 2
Это действительно не нужно в строгом смысле слова и никогда не было. То есть вы всегда можете назначить имя, например anonymous1
, anonymous2
и т.д. Но отслеживание большего количества имен, чем необходимо, всегда является проблемой.
Если это полезно, то в любом месте, где вы хотите группировать данные, не указывая имя этой группе. Я мог бы привести несколько примеров:
class foo {
class {
public:
void validate( int x ) { m_x = x; }
bool valid() { return m_exists; }
private:
int m_x;
bool m_exists;
} maybe_x;
};
В этом случае int
и bool
логически принадлежат друг другу, поэтому имеет смысл их группировать. Однако для этого конкретного примера, вероятно, имеет смысл создать фактический необязательный тип или использовать один из доступных, потому что этот шаблон, скорее всего, используется и в других местах. В других случаях эта схема группировки может быть настолько особенной, что она заслуживает того, чтобы оставаться только в этом классе.
Я действительно полагаю, однако, что анонимные классы редко используются (я использовал их только пару раз в своей жизни, вероятно). Часто, когда вы хотите группировать данные, это не относится к классу или области, а также к группировке, которая также имеет смысл в других местах.
Ответ 3
Может быть, иногда полезно создавать вложенные функции, например:
void foo() {
class {
void operator()(){
}
} bar;
bar();
}
Но теперь у нас есть lambdas, а анонимные классы остаются только по причинам совместимости.
Ответ 4
Использование анонимных классов для сохранения совместимости с существующим C-кодом.
Пример:
В некотором коде C преобладает использование typedef в сочетании с анонимными структурами.
Ответ 5
Существует пример анонимных структур, которые могут использоваться с Qt 5 системой Signal/Slot с ЛЮБЫМ классом и без требования к производным QObject:
void WorkspaceWidget::wwShowEvent()
{
//Show event: query a reload of the saved state and geometry
gcmessage("wwShowEvent "+ this->title());
struct{void* t; void operator()(){ static_cast<WorkspaceWidget*>(t)->wwReloadWindowState(); }}f;
f.t=this;
QObject::connect( &reloadStateTimer, &QTimer::timeout, f);
reloadStateTimer.start();
}
void WorkspaceWidget::wwReloadWindowState()
{
gcmessage( dynamic_cast<QObject*>(this)->metaObject()->className());
}
В принципе, мне нужно подключить сигнал таймера к производному классу, отличному от QObject, но нужно правильно передать mt "this".
QObject:: connect может быть подключен к обычной функции в Qt 5, поэтому этот анонимный класс на самом деле является функтором, который сохраняет этот указатель сам по себе, все еще передавая слот-соединение.
Ответ 6
Также вы можете делать вещи с авто в анонимном (vs2015)
struct {
auto* operator->() {return this;}
//do other functions
} mystruct;