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;
};
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
данных.
static
, вероятно, является наиболее запутанным перегруженным ключевым словом в C и C ++. Это означает разные вещи в разных местах.
static
является классом хранения , обозначающим переменные, которые существуют для времени жизни программы. Поэтому, говоря, что void f() {
static int i = 0;
}
говорит, что значение i
будет сохранено между вызовами f()
. Другие классы хранения являются по умолчанию auto
(но остерегайтесь изменения смысла в C ++ 11), extern
и register
, плюс thread_local
в C11 / C ++ 11. static
является спецификатором linkage . Таким образом, функции и переменные, помеченные static
, имеют внутреннюю связь , и поэтому являются локальными для текущей единицы перевода. Это означает, что функции, подобные static int f() {
return 3;
}
, могут ссылаться только на другие функции внутри одного и того же файла .c
. Это использование static
было устарело в C ++ 03 в пользу неназванных пространств имен. Я читал где-то, что он снова не упоминался в C ++ 11. static
можно использовать в параметре функции массива, например: void f(int a[static 4]) {
}
это указывает, что параметр a
должен иметь целочисленный массив размером не менее 4. Я думаю, что это все из них, но дайте мне знать в комментариях, если они есть, я забыл!
В отношении c ++ -> ключевое слово static
может использоваться для объявления переменных, функций, элементов данных класса и функций класса.
Вот общие обычаи в разных сценариях ( ref из MSDN )
также проверьте следующее: Статическое ключевое слово и его различные применения в C ++
Static В семействе языков C статическая переменная является той, которая существует для времени жизни единицы компиляции (исходный файл или модуль). Статическая переменная может быть объявлена по модулю и, таким образом, доступна для всех функций, определенных в том же исходном файле. Такая статическая переменная не может быть напрямую доступна из других модулей, но API внутреннего модуля может передавать указатели на статические переменные и изменять их с помощью указателей. Статическая переменная также может быть объявлена внутри тела функции, где применяются обычные правила области. Статическая переменная, объявленная внутри функции, инициализируется только тогда, когда модуль инициализируется (как правило, когда приложение загружается) и сохраняет его значения по нескольким вызовам функции, содержащей определение.
В C ++ статическая переменная также может быть членом определения класса. Доступ к статической переменной-члену определяется стандартными модификаторами доступа (private, public, protected), но все экземпляры этого класса имеют одну и ту же статическую переменную и имеют одинаковое значение. Изменение значения этой переменной влияет на все объекты класса. Volatile. Волатильное ключевое слово - это что-то общее, а не как нечто противоположное статическому. Статическая переменная может или не может быть объявлена изменчивой, как глобальная или локальная переменная. Ключевое слово volatile - это подсказка, информирующая компилятор о том, что значение переменной может измениться без знания компилятора. Поэтому оптимизатор кода компилятора не может делать предположений о текущем значении переменной и должен всегда (повторно) читать содержимое переменной.