Модификатор переопределения может использоваться для виртуальных методов и должен использоваться для абстрактных методов. Это означает, что компилятор использует последнюю определенную реализацию метода.
blockquote>public class Base { public virtual void DoIt() { } } public class Derived : Base { public override void DoIt() { } } Base b = new Derived(); b.DoIt(); // Calls Derived.DoIt
будет вызывать
]Derived.DoIt
, если это переопределяетBase.DoIt
.Новый модификатор инструктирует компилятор использовать реализацию вашего дочернего класса вместо реализации родительского класса. Любой код, который не ссылается на ваш класс, но родительский класс будет использовать реализацию родительского класса.
blockquote>public class Base { public virtual void DoIt() { } } public class Derived : Base { public new void DoIt() { } } Base b = new Derived(); Derived d = new Derived(); b.DoIt(); // Calls Base.DoIt d.DoIt(); // Calls Derived.DoIt
Сначала вызовет
Base.DoIt
, затемDerived.DoIt
. Они фактически представляют собой два совершенно разных метода, которые имеют одно и то же имя, а не производный метод, переопределяющий базовый метод.Источник: Блог Microsoft
Файл .h - это, по сути, просто код, который во время компиляции помещается над любым .cpp (или .h файлом, если на то пошло), в который он включен. Поэтому вы МОЖЕТЕ просто поместить любой код из файла .cpp в .h, и он должен компилироваться нормально.
Однако важен дизайн. Ваш код (например, ваше перечисление) ДОЛЖЕН быть помещен в файл .h, если вам нужно предоставить его коду, который вы включаете в файл .h. Однако, если перечисление относится только к коду в реализации .cpp вашего заголовка, вам следует инкапсулировать его только в файл .cpp.
Да, ваше определение enum может идти в вашем файле заголовка (.h
). Не повторяйте определение в вашем файле .cpp
.
Да, конечно, вы можете поместить его в файл .h. Единственные вещи, которые не должны попадать в файл .h, - это вещи, которые могут вызвать проблемы, если они будут включены в более чем один объект, такие как инициализаторы глобальных объектов.
У меня недостаточно информации, но, возможно, вы можете объявить перечисление не только в .h, но и внутри класса. Не забудьте ограничить область видимости переменной.
если перечисление относится к определенному классу, вы должны объявить его внутри класса.
Не забудьте использовать защиту включения заголовка в таких заголовках, как:
#ifndef header_name_h
#define header_name_h
...
#endif
Это поможет вам придерживаться одного правила определения, когда несколько заголовков включают ваш заголовок.
Обновление:
У меня есть так как обнаружено, что последние версии Visual Studio и gcc позволяют:
#pragma once
Кроме того, никогда не было:
using namespace <name>;
в заголовке, так как это может вызвать странные проблемы с неоднозначностью.
Одно правило определения допускает это на 3.2 / 5
. Все перечисленное можно поместить в заголовки и многократно включать в разные единицы перевода.
Может быть более одного определения типа класса (пункт 9), типа перечисления (7.2), встроенной функции с внешней связью (7.1.2), шаблона класса (пункт 14), без -статический шаблон функции (14.5.5), статический член данных шаблона класса (14.5.1.3), функция-член шаблона класса (14.5.1.1) или специализация шаблона, для которой не указаны некоторые параметры шаблона (14.7, 14.5 .4) в программе при условии, что каждое определение появляется в разных единицах перевода и при условии, что определения удовлетворяют следующим требованиям:
Требования по существу сводятся к тому, что каждое определение должно быть одинаковым. Обратите внимание: если у самого типа перечисления нет имени, то это правило не распространяется. Каждое его определение в другой единице перевода определяет новый тип перечисления и не конфликтует друг с другом.
Помещение их в заголовок - хорошее место, если оно должно быть публичным. Помещение их в файл реализации - хорошее место, если предполагается, что он будет частным для этого единственного файла. В последнем случае либо поместите их в безымянное пространство имен, либо сделайте их безымянными (как в случае с вашим примером перечисления), чтобы оно не могло конфликтовать с другим перечислением с таким же именем.
t конфликтовать друг с другом.Помещение их в заголовок - хорошее место, если оно должно быть публичным. Помещение их в файл реализации - хорошее место, если предполагается, что он будет частным для этого единственного файла. В последнем случае либо поместите их в безымянное пространство имен, либо сделайте их безымянными (как в случае с вашим примером перечисления), чтобы оно не могло конфликтовать с другим перечислением с таким же именем.
t конфликтовать друг с другом.Помещение их в заголовок - хорошее место, если оно должно быть публичным. Помещение их в файл реализации - хорошее место, если предполагается, что он будет частным для этого единственного файла. В последнем случае либо поместите их в безымянное пространство имен, либо сделайте их безымянными (как в случае с вашим примером перечисления), чтобы оно не могло конфликтовать с другим перечислением с таким же именем.
В общем, перечисление будет использоваться как определение типа и должно всегда быть в файле заголовка. Следует подумать о его объеме.
Если перечисление просто помещено за пределы какой-либо области в заголовке, оно будет глобально доступно для всего, что включает файл заголовка. Если вместо этого вы хотите, чтобы перечисление было доступно только самому классу, вы можете поместить его в частный раздел класса.
В общем, вы не должны делать перечисление глобальным, вместо этого вы должны поместить его в пространство имен или в публичный раздел класса. Затем вы можете получить доступ к перечислению с помощью
NamespaceOrClass::EnumValue
. Кроме того, в качестве примечания, перечисления автоматически повторяют значения из первого, которое вы даете (или 0).
enum
{
kCP_AboutBox_IconViewID = 1,
kCP_AboutBox_AppNameViewID = 2,
kCP_AboutBox_VersionViewID = 3,
kCP_AboutBox_DescriptionViewID = 4,
kCP_AboutBox_CopyrightViewID = 5
};
Точно так же, как
enum
{
kCP_AboutBox_IconViewID = 1,
kCP_AboutBox_AppNameViewID,
kCP_AboutBox_VersionViewID,
kCP_AboutBox_DescriptionViewID,
kCP_AboutBox_CopyrightViewID
};
Это не проблема или ошибка, на самом деле просто стилистика.