Подтвердить что ты не робот

Использование локального класса в функции С++

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

Существует общий интерфейс 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 для обработки входящего события.

Какова область внутренней структуры объекта структуры? Это очень интересно. Есть ли какие-то документы об этом?

4b9b3361

Ответ 1

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

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

Что делает интересные локальные классы: , если они реализуют некоторый интерфейс (например, ваш код), то вы можете создавать экземпляры его (используя 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. Локальный класс не должен содержать статических данных.

Ответ 2

\ 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

Ответ 3

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