2012-04-09 6 views
14

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

Могу ли я иметь пример, который действительно нуждается в анонимном классе?

+1

Почему у вас есть анонимная-структура? – Nawaz

+0

@ Наваз Ах да, ты прав. Я мог бы быть той же причиной, почему она существует на C. В любом случае мне любопытно, что конкретно для C++. Поскольку C++ - это много другой язык с C. – Eonil

ответ

19

Особенность есть потому, что struct и class - это то же самое - все, что вы можете сделать с одним, вы можете сделать с другим. Он служит точно такой же цели, как анонимный struct в C; когда вы хотите сгруппировать некоторые вещи вместе и объявить один или несколько экземпляров, но не нужно ссылаться на этот тип по имени.

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

2

Может быть, это иногда полезно сделать вложенные функции, такие как:

void foo() { 
    class { 
    void operator()(){ 
    } 
    } bar; 
    bar(); 
} 

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

4

Это действительно не нужно в строгом смысле слова и никогда не было. То есть вы всегда можете назначить имя, например 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 логически связаны друг с другом, так что имеет смысл сгруппировать их. Однако для этого конкретного примера, вероятно, имеет смысл создать фактический необязательный тип или использовать один из доступных, потому что этот шаблон, скорее всего, используется и в других местах. В других случаях эта схема группировки может быть настолько особенной, что она заслуживает того, чтобы оставаться только в этом классе.

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

+1

. Вашему примеру понадобится конструктор для обеспечения инварианта класса (это либо значение является допустимым, либо флагом является ложным); но вы не можете объявить конструктор для анонимного класса. –

+0

@MikeSeymour: хороший пункт. Думаю, придется позаботиться об этом по-другому. Возможно, с C++ 11 в инициализаторе класса это сделало бы. Как я уже сказал, это, скорее всего, очень редко используется. – LiKao

1

Использование анонимных классов предназначено для сохранения совместимости с существующим C-кодом. Пример:

В некотором C-коде распространено использование typedef в сочетании с анонимными структурами.

1

Существует пример анонимных структур, которые могут быть использованы с Signal/системой Slot Qt 5'с любым классом и без требования 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, поэтому этот анонимный класс на самом деле является функтором, который удерживает этот указатель сам по себе, все еще передавая соединение по слоту.

+0

Но лучше заменить лямбдой в C++ 11 – paulm

+0

На момент написания статьи QObject не понял, что такое «Лямбда», но потом они исправили его. –

0

Также вы можете сделать что-то с авто в анонимном (vs2015)

struct { 

    auto* operator->() {return this;} 
    //do other functions 

} mystruct; 
Смежные вопросы