Когда следует использовать класс, а не структуру в C++?

StackOverflow https://stackoverflow.com/questions/54585

  •  09-06-2019
  •  | 
  •  

Вопрос

В каких случаях лучше использовать struct против class на С++?

Это было полезно?

Решение

Различия между class и struct в C++ заключаются в том, что структуры имеют значение по умолчанию. public члены, базы и классы имеют значение по умолчанию private члены и базы.И классы, и структуры могут иметь смесь public, protected и private члены, могут использовать наследование и могут иметь функции-члены.

Я бы рекомендовал использовать структуры как старые структуры данных без каких-либо классовых функций и использовать классы как совокупные структуры данных с private данные и функции-члены.

Другие советы

Как отмечают все остальные, на самом деле существует только два реальных языковых различия:

  • struct по умолчанию публичный доступ и class по умолчанию используется частный доступ.
  • При наследовании, struct по умолчанию public наследование и class по умолчанию private наследование.(По иронии судьбы, как и во многих других случаях в C++, по умолчанию используется обратный порядок действий: public наследование, безусловно, является более распространенным выбором, но люди редко заявляют structпросто чтобы сэкономить на вводе "public"Ключевое слово.

Но реальная разница на практике заключается между class/struct который объявляет конструктор/деструктор и тот, который этого не делает.Существуют определенные гарантии для типа POD «простых старых данных», которые больше не применяются после того, как вы возьмете на себя создание класса.Чтобы сохранить это различие ясным, многие люди намеренно используют только structs для типов POD, и, если они вообще собираются добавлять какие-либо методы, используйте classэс.В остальном разница между двумя приведенными ниже фрагментами бессмысленна:

class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(Кстати, вот ветка с некоторыми хорошими объяснениями того, что на самом деле означает «тип POD»: Что такое типы POD в C++?)

В существующих ответах много заблуждений.

Оба class и struct объявить класс.

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

Но, помимо синтаксиса, только Причина выбора одного из других — это условности/стиль/предпочтения.

Некоторым людям нравится придерживаться struct ключевое слово для классов без функций-членов, поскольку результирующее определение «выглядит» как простая структура из C.

Точно так же некоторые люди любят использовать class ключевое слово для классов с функциями-членами и private data, потому что там написано «класс» и поэтому выглядит как примеры из их любимой книги по объектно-ориентированному программированию.

Реальность такова, что это полностью зависит от вас и вашей команды, и для вашей программы это не будет иметь никакого значения.

Следующие два класса абсолютно эквивалентны во всем, кроме названия:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

Вы даже можете переключать ключевые слова при переобъявлении:

class Foo;
struct Bar;

(хотя это нарушает сборки Visual Studio из-за несоответствия, поэтому компилятор выдаст предупреждение, когда вы это сделаете.)

и оба следующих выражения имеют значение true:

std::is_class<Foo>::value
std::is_class<Bar>::value

Однако обратите внимание, что вы не можете переключать ключевые слова, когда переопределение;это происходит только потому, что (в соответствии с правилом одного определения) повторяющиеся определения классов в единицах перевода должны «состоят из одной и той же последовательности токенов».Это означает, что вы даже не можете обменять const int member; с int const member;, и не имеет ничего общего с семантикой class или struct.

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

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 

Из Часто задаваемые вопросы по C++ Lite:

Члены и базовые классы структуры по умолчанию являются общедоступными, а в классе они по умолчанию являются частными.Примечание:вам следует явно сделать свои базовые классы общедоступными, частными или защищенными, а не полагаться на значения по умолчанию.

В остальном структура и класс функционально эквивалентны.

Ладно, хватит этих кристально чистых разговоров о техно.С эмоциональной точки зрения большинство разработчиков проводят четкое различие между классом и структурой.Структура просто ощущается как открытая куча битов с очень небольшими возможностями инкапсуляции или функциональности.Класс чувствует себя живым и ответственным членом общества с интеллектуальными сервисами, сильным барьером инкапсуляции и четко определенным интерфейсом.Поскольку это значение уже имеет большинство людей, вам, вероятно, следует использовать ключевое слово struct, если у вас есть класс, который имеет очень мало методов и имеет общедоступные данные (такие вещи действительно существуют в хорошо спроектированных системах!), Но в противном случае вам, вероятно, следует использовать класс ключевое слово.

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

typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;

void processMessage(unsigned char *rawMessage)
{
    tMessageType *messageFields = (tMessageType *)rawMessage;
    printf("MessageId is %d\n", messageFields->messageId);
}

Очевидно, это то же самое, что вы бы сделали в C, но я считаю, что накладные расходы, связанные с декодированием сообщения в класс, обычно того не стоят.

Вы можете использовать «struct» в C++, если пишете библиотеку, внутренняя часть которой — C++, но API может быть вызван кодом C или C++.Вы просто создаете один заголовок, содержащий структуры и глобальные функции API, которые вы предоставляете коду C и C++, следующим образом:

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif

// Put your C struct's here
struct foo
{
    ...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;

// Put your C API functions here
void bar(foo *fun);

#ifdef __cpp
}
#endif

Затем вы можете написать функцию bar() в файле C++, используя код C++, и сделать ее вызываемой из C, и два мира смогут обмениваться данными через объявленную структуру.Конечно, при смешивании C и C++ есть и другие предостережения, но это упрощенный пример.

Как все говорят, единственная реальная разница — это доступ по умолчанию.Но я особенно использую структуру, когда мне не нужна какая-либо инкапсуляция с простым классом данных, даже если я реализую некоторые вспомогательные методы.Например, когда мне нужно что-то вроде этого:

struct myvec {
    int x;
    int y;
    int z;

    int length() {return x+y+z;}
};

Структуры (POD, в более общем смысле) удобны, когда вы предоставляете C-совместимый интерфейс с реализацией C++, поскольку они переносимы через языковые границы и форматы компоновщика.

Если вас это не беспокоит, то я полагаю, что использование «структуры» вместо «класса» является хорошим средством передачи намерений (как сказал @ZeroSignal выше).Структуры также имеют более предсказуемую семантику копирования, поэтому они полезны для данных, которые вы собираетесь записать на внешний носитель или отправить по сети.

Структуры также удобны для различных задач метапрограммирования, например, шаблонов свойств, которые просто предоставляют набор зависимых определений типов:

template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

...Но на самом деле это просто использование общедоступного уровня защиты структуры по умолчанию...

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

Тем не менее, я склонен использовать структуры в C++ так же, как и в C#, подобно тому, что сказал Брайан.Структуры — это простые контейнеры данных, а классы используются для объектов, которые должны воздействовать на данные, а не просто удерживать их.

Чтобы ответить на мой собственный вопрос (беззастенчиво): Как уже упоминалось, привилегии доступа — единственная разница между ними в C++.

Я склонен использовать структуру только для хранения данных.Я позволю ему получить несколько вспомогательных функций, если это облегчит работу с данными.Однако, как только данные требуют управления потоком (т.геттеры/сеттеры, которые поддерживают или защищают внутреннее состояние) или начинают приобретать какие-либо основные функции (в основном более объектные), он будет «обновлен» до класса, чтобы лучше передавать намерения.

Они во многом одно и то же.Благодаря магии C++ структура может содержать функции, использовать наследование, создаваться с использованием «нового» и т. д. точно так же, как класс.

Единственное функциональное отличие состоит в том, что класс начинается с частных прав доступа, а структура — с общедоступных.Это поддержка обратной совместимости с C.

На практике я всегда использовал структуры в качестве держателей данных, а классы — в качестве объектов.

Сорт.

Члены класса по умолчанию являются частными.

class test_one {
    int main_one();
};

Эквивалентно

class test_one {
  private:
    int main_one();
};

Итак, если вы попробуете

int two = one.main_one();

Мы получим ошибку: main_one is private потому что он недоступен.Мы можем решить его, инициализируя его, указав его публичный т.е.

class test_one {
  public:
    int main_one();
};

Структура.

Структура — это класс, члены которого по умолчанию являются общедоступными.

struct test_one {
    int main_one;
};

Означает main_one является частным, т.е.

class test_one {
  public:
    int main_one;
};

Я использую структуры для структур данных, где участники могут получить любую ценность, так проще.

это одно и то же с разными настройками по умолчанию (по умолчанию частные для class, и общедоступный по умолчанию для struct), поэтому теоретически они полностью взаимозаменяемы.

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

Структуры по умолчанию имеют публичный доступ, а классы по умолчанию имеют частный доступ.

Лично я использую структуры для объектов передачи данных или в качестве объектов значений.При таком использовании я объявляю все члены константными, чтобы предотвратить их модификацию другим кодом.

Преимущество struct над class заключается в том, что он сохраняет одну строку кода, если придерживается принципа «сначала публичные члены, затем частные».В этом свете я нахожу ключевое слово class бесполезный.

Вот еще одна причина использовать только struct и никогда class.Некоторые рекомендации по стилю кода для C++ предлагают использовать строчные буквы для макросов функций, поскольку при преобразовании макроса во встроенную функцию имя не нужно менять.То же самое.У вас есть красивая структура в стиле C, и однажды вы обнаруживаете, что вам нужно добавить конструктор или какой-нибудь удобный метод.Вы меняете его на class?Повсюду?

Различие между structпесок classes — это слишком много хлопот, мешающих делать то, что нам следует делать — программирование.Как и многие другие проблемы C++, она возникает из-за сильного стремления к обратной совместимости.

Технически оба одинаковы в C++ - например, структура может иметь перегруженные операторы и т.д.

Однако :

Я использую структуры, когда хочу передавать информацию о нескольких типах одновременно, я использую классы, когда я имею дело с «функциональным» объектом.

Надеюсь, поможет.

#include <string>
#include <map>
using namespace std;

struct student
{
    int age;
    string name;
    map<string, int> grades
};

class ClassRoom
{
    typedef map<string, student> student_map;
  public :
    student getStudentByName(string name) const 
    { student_map::const_iterator m_it = students.find(name); return m_it->second; }
  private :
    student_map students;
};

Например, я возвращаю здесь struct Student в методах get...() — наслаждайтесь.

Когда вы бы выбрали использовать struct и когда использовать класс в C ++?

я использую struct когда я определяю functors и POD.В противном случае я использую class.

// '()' is public by default!
struct mycompare : public std::binary_function<int, int, bool>
{
    bool operator()(int first, int second)
    { return first < second; }
};

class mycompare : public std::binary_function<int, int, bool>
{
public:
    bool operator()(int first, int second)
    { return first < second; }
};

Я использую структуры, когда мне нужно создать тип или функтор POD.

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

Как отмечали другие

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

Есть четкая рекомендация Страуструпа/Саттера о том, когда что использовать:

Используйте class, если у класса есть инвариант;используйте структуру, если элементы данных могут изменяться независимо

Однако имейте в виду, что нецелесообразно заранее объявлять что-либо.как класс(class X;) и определите его как struct (struct X { ... }).Он может работать на некоторых компоновщиках (например, g++) и может давать сбой на других (например, MSVC), так что вы окажетесь в аду разработчика.

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

Например:Чтение/запись данных из файлов, потоков сокетов и т. д.Передача аргументов функции в структуру, где аргументов функции слишком много, а синтаксис функции выглядит слишком длинным.

Технически нет большой разницы между классом и структурой, за исключением доступности по умолчанию.Более того, то, как вы его используете, зависит от стиля программирования.

Я думал, что Structs был задуман как структура данных (например, массив информации с несколькими типами данных), а классы были предназначены для упаковки кода (например, коллекции подпрограмм и функций).

:(

Я никогда не использую «структуру» в C++.

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

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

Например.

class PublicInputData {
    //data members
 };
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top