Завершение CreateTimerQueueTimer в WM_CLOSE [дубликат]

Члены класса:

Для деструктора pure virtual требуется реализация.

Объявление деструктора по-прежнему требует от вас определения (в отличие от обычной функции):

struct X
{
    virtual ~X() = 0;
};
struct Y : X
{
    ~Y() {}
};
int main()
{
    Y y;
}
//X::~X(){} //uncomment this line for successful definition

Это происходит потому, что деструкторы базового класса вызывается, когда объект уничтожается неявно, поэтому требуется определение.

virtual методы должны быть реализованы или определены как чистые.

Это похоже на методы не virtual без определения, с добавлением аргументов, которые генерирует чистая декларация dummy vtable, и вы можете получить ошибку компоновщика без использования функции:

struct X
{
    virtual void foo();
};
struct Y : X
{
   void foo() {}
};
int main()
{
   Y y; //linker error although there was no call to X::foo
}

Чтобы это сработало, объявите X::foo() чистым:

struct X
{
    virtual void foo() = 0;
};

Non- virtual

Некоторые члены должны быть определены, даже если они явно не используются:

struct A
{ 
    ~A();
};

Следующие ошибки приведут к ошибке:

A a;      //destructor undefined

Реализация может быть встроенной в самом определении класса:

struct A
{ 
    ~A() {}
};

или снаружи:

A::~A() {}

Если реализация вне определения класса, но в заголовке, методы должны быть отмечены как inline, чтобы предотвратить множественное определение.

Все используемые методы-члены должны быть определены, если они используются.

Общей ошибкой является отказ от квалификации имени:

struct A
{
   void foo();
};

void foo() {}

int main()
{
   A a;
   a.foo();
}

Определение должно быть

void A::foo() {}

static. Члены данных должны быть определены вне класса в единственная единица перевода:

struct X
{
    static int x;
};
int main()
{
    int x = X::x;
}
//int X::x; //uncomment this line to define X::x

Инициализатор может быть предоставлен для элемента данных static const типа интеграла или перечисления в определении класса; однако odr-использование этого элемента по-прежнему потребует определения области пространства имен, как описано выше. C ++ 11 позволяет инициализировать внутри класса для всех членов static const данных.

-1
задан stamaimer 20 December 2013 в 12:12
поделиться

3 ответа

static, вероятно, является наиболее запутанным перегруженным ключевым словом в C и C ++. Это означает разные вещи в разных местах.

  • Внутри функций static является классом хранения , обозначающим переменные, которые существуют для времени жизни программы. Поэтому, говоря, что
    void f() {
        static int i = 0;
    }
    
    говорит, что значение i будет сохранено между вызовами f(). Другие классы хранения являются по умолчанию auto (но остерегайтесь изменения смысла в C ++ 11), extern и register, плюс thread_local в C11 / C ++ 11.
  • В области файлов (или области пространства имен в C ++) static является спецификатором linkage . Таким образом, функции и переменные, помеченные static, имеют внутреннюю связь , и поэтому являются локальными для текущей единицы перевода. Это означает, что функции, подобные
     static int f() {
         return 3;
     }
    
    , могут ссылаться только на другие функции внутри одного и того же файла .c. Это использование static было устарело в C ++ 03 в пользу неназванных пространств имен. Я читал где-то, что он снова не упоминался в C ++ 11.
  • В C ++, когда применяется к членной функции или переменной-члену класса, это означает, что функции или переменной не требуется экземпляр класса в чтобы получить доступ. Между «классными статическими» функциями-членами / переменными и глобальными функциями / переменными мало что происходит с реализацией, за исключением того, что спецификаторы доступа класса C ++ применяются к членам.
  • Последний: на C99 (но не на C ++ ), static можно использовать в параметре функции массива, например:
    void f(int a[static 4]) {
    }
    
    это указывает, что параметр a должен иметь целочисленный массив размером не менее 4.

Я думаю, что это все из них, но дайте мне знать в комментариях, если они есть, я забыл!

5
ответ дан 2 revs 23 August 2018 в 16:43
поделиться

В отношении c ++ -> ключевое слово static может использоваться для объявления переменных, функций, элементов данных класса и функций класса.

Вот общие обычаи в разных сценариях ( ref из MSDN )

  • Когда вы объявляете переменную или функцию в области файла (глобальная и / или область пространства имен), ключевое слово static указывает, что переменная или функция имеют внутреннюю связь. Когда вы объявляете переменную, переменная имеет статическую продолжительность, и компилятор инициализирует ее до 0, если вы не укажете другое значение.
  • Когда вы объявляете переменную в функции, ключевое слово static указывает, что переменная сохраняет свое состояние между вызовами этой функции.
  • Когда вы объявляете член данных в объявлении класса, ключевое слово static указывает, что одна копия члена разделяется всеми экземплярами класса. Статический член данных должен быть определен в области файлов. Интегрированный элемент данных, который вы объявляете как const static, может иметь инициализатор.
  • Когда вы объявляете функцию-член в объявлении класса, ключевое слово static указывает, что функция разделяется всеми экземплярами класса. Статическая функция-член не может получить доступ к члену экземпляра, потому что функция не имеет неявного этого указателя. Чтобы получить доступ к члену экземпляра, объявите функцию с параметром, который является указателем экземпляра или ссылкой.
  • Вы не можете объявлять члены объединения как статические. Однако объявленный глобально анонимный союз должен быть явно объявлен статическим.

также проверьте следующее: Статическое ключевое слово и его различные применения в C ++

использование статического ключевого слова

0
ответ дан Community 23 August 2018 в 16:43
поделиться

Static В семействе языков C статическая переменная является той, которая существует для времени жизни единицы компиляции (исходный файл или модуль). Статическая переменная может быть объявлена ​​по модулю и, таким образом, доступна для всех функций, определенных в том же исходном файле. Такая статическая переменная не может быть напрямую доступна из других модулей, но API внутреннего модуля может передавать указатели на статические переменные и изменять их с помощью указателей. Статическая переменная также может быть объявлена ​​внутри тела функции, где применяются обычные правила области. Статическая переменная, объявленная внутри функции, инициализируется только тогда, когда модуль инициализируется (как правило, когда приложение загружается) и сохраняет его значения по нескольким вызовам функции, содержащей определение.

В C ++ статическая переменная также может быть членом определения класса. Доступ к статической переменной-члену определяется стандартными модификаторами доступа (private, public, protected), но все экземпляры этого класса имеют одну и ту же статическую переменную и имеют одинаковое значение. Изменение значения этой переменной влияет на все объекты класса. Volatile. Волатильное ключевое слово - это что-то общее, а не как нечто противоположное статическому. Статическая переменная может или не может быть объявлена ​​изменчивой, как глобальная или локальная переменная. Ключевое слово volatile - это подсказка, информирующая компилятор о том, что значение переменной может измениться без знания компилятора. Поэтому оптимизатор кода компилятора не может делать предположений о текущем значении переменной и должен всегда (повторно) читать содержимое переменной.

2
ответ дан nuke_infer 23 August 2018 в 16:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: