Использование локального класса в функции C ++ - PullRequest
35 голосов
/ 19 апреля 2011

Я вижу некоторое использование внутренней структуры в функции c ++.

Существует общий интерфейс IBase. Вот черновик кода.

class IBase
{
    virtual Method()=0;
}

vector<IBase*> baseList;

Затем функция определила внутренний класс на основе этого IBase, а затем вставила объект внутреннего класса в baseList.

void func()
{
    struct Object : public IBase
    {
        virtual Method()
        {
            // Method of Object in func
        }
    }

    IBase* base = new Object();
    baseList->push(base);

}

Кажется странным использование, но хорошая реализация шаблона создания сообщений / событий.

Другие потоки могут использовать этот baseList для обработки входящего события.

Какова область внутренней структуры "struct Object"? Это очень интересно. Есть ли какие-то документы, говорящие об этом?

Ответы [ 3 ]

42 голосов
/ 19 апреля 2011

Какова область внутренней структуры "struct Object"?

Область действия локальных классов - это функция, в которой они определены. Но это само по себе неинтересно.

Что делает локальные классы интересными, так это то, что , если реализуют некоторый интерфейс (как это делает ваш код), то вы можете создать его экземпляры (используя new) и вернуть их (например, как std::vector<IBase*>), что делает реализацию доступной через указатель базового класса даже вне функции.

Некоторые другие факты о местных классах:

  • Они не могут определять статические переменные-члены.

  • Они не могут получить доступ к нестатическим «автоматическим» локальным переменным функции включения. Но они могут получить доступ к static переменным.

  • Они могут использоваться в функциях шаблона.

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

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

  • Локальные классы используются для создания функций батута , обычно известных как thunks .


РЕДАКТИРОВАТЬ * * тысяча пятьдесят-одна

Некоторые ссылки из Стандарта (2003)

9.8 Локальные объявления классов [class.local]

\ 1. Класс может быть определен в определении функции; такой класс называется местный класс. Наименование локальный класс является локальным объем. Локальный класс находится в области видимости охватывающей области, и имеет тот же доступ к именам за пределами функционировать так же, как и ограждающие функция. Объявления в местном класс может использовать только имена типов, статические переменные, внешние переменные и функции и счетчики из объем ограждения.

[Example:

int x;
void f()
{
   static int s ;
   int x;
   extern int g();

   struct local {
      int g() { return x; } // error: x is auto
      int h() { return s; } // OK
      int k() { return ::x; } // OK
      int l() { return g(); } // OK
   };
// ...
}
local* p = 0; // error: local not in scope

—end example]

\ 2. Функция включения не имеет специального доступа к членам местного учебный класс; подчиняется обычным правилам доступа (пункт 11). Функции-члены местный класс должен быть определен в пределах их определение класса, если они определены вообще.

\ 3. Если класс X является локальным классом, вложенный класс Y может быть объявлен в класс X и позже определены в определение класса X или позже определяется в той же области, что и определение класса X. Вложенный класс внутри локального класса есть локальный класс.

\ 4. Локальный класс не должен иметь статических членов данных.

4 голосов
/ 28 марта 2012

\ 4.Локальный класс не должен иметь статических членов данных.

НО вы можете сделать это, внутри локального класса

int GetCount()
{
    class _local
    {
    public:
        static int Count(int count = std::numeric_limits<int>::max())
        {
            static int count_ = 0;
            if (count != std::numeric_limits<int>::max()) count_ = count;
            return count_;
        }

        static float Operation(float  a, float  b)
        {
            _local::Count(_local::Count() + 1);
            return a;
        }
    };
   _local::Count(0);
   CALLBACK( _local::Operation);
   return _local::Count();
}

_local :: Count можно использовать для чтения и записи статического в противном случаепеременная

-aydin

2 голосов
/ 19 апреля 2011

Это нормальный C ++. scope из struct Object является только функцией func. Однако вы все еще можете использовать объекты этого типа, не зная, к какому конкретному типу они относятся, поскольку они наследуются от IBase. Это используется для инкапсуляции реализации.

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