Перечисления: они могут сделать в.h или должны остаться в .cpp?

Модификатор переопределения может использоваться для виртуальных методов и должен использоваться для абстрактных методов. Это означает, что компилятор использует последнюю определенную реализацию метода.

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

24
задан Johannes Schaub - litb 16 August 2009 в 15:38
поделиться

7 ответов

Файл .h - это, по сути, просто код, который во время компиляции помещается над любым .cpp (или .h файлом, если на то пошло), в который он включен. Поэтому вы МОЖЕТЕ просто поместить любой код из файла .cpp в .h, и он должен компилироваться нормально.

Однако важен дизайн. Ваш код (например, ваше перечисление) ДОЛЖЕН быть помещен в файл .h, если вам нужно предоставить его коду, который вы включаете в файл .h. Однако, если перечисление относится только к коду в реализации .cpp вашего заголовка, вам следует инкапсулировать его только в файл .cpp.

41
ответ дан 28 November 2019 в 18:21
поделиться

Да, ваше определение enum может идти в вашем файле заголовка (.h). Не повторяйте определение в вашем файле .cpp.

4
ответ дан mipadi 28 November 2019 в 18:21
поделиться

Да, конечно, вы можете поместить его в файл .h. Единственные вещи, которые не должны попадать в файл .h, - это вещи, которые могут вызвать проблемы, если они будут включены в более чем один объект, такие как инициализаторы глобальных объектов.

3
ответ дан Andrew Medico 28 November 2019 в 18:21
поделиться

У меня недостаточно информации, но, возможно, вы можете объявить перечисление не только в .h, но и внутри класса. Не забудьте ограничить область видимости переменной.
если перечисление относится к определенному классу, вы должны объявить его внутри класса.

0
ответ дан Matthieu 28 November 2019 в 18:21
поделиться

Не забудьте использовать защиту включения заголовка в таких заголовках, как:

#ifndef header_name_h
#define header_name_h
...
#endif

Это поможет вам придерживаться одного правила определения, когда несколько заголовков включают ваш заголовок.

Обновление:

У меня есть так как обнаружено, что последние версии Visual Studio и gcc позволяют:

#pragma once

Кроме того, никогда не было:

using namespace <name>;

в заголовке, так как это может вызвать странные проблемы с неоднозначностью.

8
ответ дан 28 November 2019 в 18:21
поделиться

Одно правило определения допускает это на 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 конфликтовать друг с другом.

Помещение их в заголовок - хорошее место, если оно должно быть публичным. Помещение их в файл реализации - хорошее место, если предполагается, что он будет частным для этого единственного файла. В последнем случае либо поместите их в безымянное пространство имен, либо сделайте их безымянными (как в случае с вашим примером перечисления), чтобы оно не могло конфликтовать с другим перечислением с таким же именем.

3
ответ дан 28 November 2019 в 18:21
поделиться

В общем, перечисление будет использоваться как определение типа и должно всегда быть в файле заголовка. Следует подумать о его объеме.

Если перечисление просто помещено за пределы какой-либо области в заголовке, оно будет глобально доступно для всего, что включает файл заголовка. Если вместо этого вы хотите, чтобы перечисление было доступно только самому классу, вы можете поместить его в частный раздел класса.

В общем, вы не должны делать перечисление глобальным, вместо этого вы должны поместить его в пространство имен или в публичный раздел класса. Затем вы можете получить доступ к перечислению с помощью

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
};

Это не проблема или ошибка, на самом деле просто стилистика.

4
ответ дан 28 November 2019 в 18:21
поделиться
Другие вопросы по тегам:

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