Каковы различия между структурой и классом в C++?

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

Вопрос

Этот вопрос был уже спрашивали в контексте C#/.Net.

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

Начну с очевидной разницы:

  • Если вы не укажете public: или private:, члены структуры по умолчанию являются общедоступными;члены класса по умолчанию являются частными.

Я уверен, что в неясных уголках спецификации C++ можно найти и другие различия.

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

Решение

Вы забываете о втором сложном различии между классами и структурами.

Процитировал стандарт (§11.2.2 в C++98–C++11):

В отсутствие спецификатор доступаДля базового класса публика предполагается, когда полученный класс объявляется структура и приватный предполагается при объявлении класса сорт.

И просто для полноты картины, более широко известная разница между классом и структурой определена в (11.2):

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

Дополнительная разница:ключевое слово class может использоваться для объявления параметров шаблона, а struct ключевое слово не может быть использовано таким образом.

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

Цитирование Часто задаваемые вопросы по C++,

7.8] В чем разница между структурой ключевых слов и классом?

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

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

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

Стоит помнить о происхождении C++ и совместимости с C.

В C есть структуры, в нем нет понятия инкапсуляции, поэтому все общедоступно.

Быть общедоступным по умолчанию обычно считается плохой идеей при использовании объектно-ориентированного подхода, поэтому при создании формы C, которая изначально способствует ООП (вы можете использовать ООП в C, но это вам не поможет), что и было В C++ (первоначально «C With Classes») имеет смысл по умолчанию сделать членов закрытыми.

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

Итак, новое ключевое слово, class была представлена ​​как структура, но по умолчанию закрытая.

Если бы C++ возник с нуля, без истории, то, вероятно, в нем было бы только одно такое ключевое слово.Это также, вероятно, не оказало бы того воздействия, которое произвело.

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

Члены класса по умолчанию являются частными.По умолчанию члены структуры являются общедоступными.Кроме этого других различий нет.Также см этот вопрос.

По мнению Страуструпа в Язык программирования С++:

Какой стиль вы выберете, зависит от обстоятельств и вкуса.Обычно я предпочитаю использовать struct для классов, у которых все данные общедоступны.Я думаю о таких классах как о «не совсем правильных типах, просто структурах данных».

Функционально нет никакой разницы, кроме публичного/частного

STRUCT — это тип абстрактного типа данных, который делит заданный фрагмент памяти в соответствии со спецификацией структуры.Структуры особенно полезны при сериализации/десериализации файлов, поскольку структуру часто можно записать в файл дословно.(т.е.Получите указатель на структуру, используйте макрос SIZE, чтобы вычислить количество байтов для копирования, затем переместите данные в структуру или из нее.)

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

По сути, структуры — это данные, классы — это код.

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

Помимо того, что каждый из них представляет собой отдельный тип абстракции, классы предоставляют решения головоломки с именованием кода C.Поскольку вы не можете использовать более одной функции с одним и тем же именем, разработчики использовали шаблон _().напримерmathlibextreme_max().Группируя API в классы, схожие функции (здесь мы называем их «методами») можно сгруппировать вместе и защитить от именования методов в других классах.Это позволяет программисту лучше организовать свой код и увеличить количество повторного использования кода.По крайней мере, в теории.

1) Члены класса по умолчанию являются частными, а члены структуры по умолчанию являются общедоступными.

Например, программа 1 не компилируется, а программа 2 работает нормально.

// Program 1
#include <stdio.h>

class Test {
    int x; // x is private
};
int main()
{
  Test t;
  t.x = 20; // compiler error because x is private
  getchar();
  return 0;
}
Run on IDE
// Program 2
#include <stdio.h>

struct Test {
    int x; // x is public
};
int main()
{
  Test t;
  t.x = 20; // works fine because x is public
  getchar();
  return 0;
}

2) При получении структуры из класса/структуры спецификатор доступа по умолчанию для базового класса/структуры является общедоступным.А при наследовании класса спецификатор доступа по умолчанию является закрытым.

Например, программа 3 не компилируется, а программа 4 работает нормально.

// Program 3
#include <stdio.h>

class Base {
public:
    int x;
};

class Derived : Base { }; // is equilalent to class Derived : private Base {}

int main()
{
  Derived d;
  d.x = 20; // compiler error becuase inheritance is private
  getchar();
  return 0;
}
Run on IDE
// Program 4
#include <stdio.h>

class Base {
public:
    int x;
};

struct Derived : Base { }; // is equilalent to struct Derived : public Base {}

int main()
{
  Derived d;
  d.x = 20; // works fine becuase inheritance is public
  getchar();
  return 0;
}

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

Не в спецификации, нет.Основная разница заключается в ожиданиях программистов, когда они прочитают ваш код через 2 года.структуры часто считаются POD.Структуры также используются в метапрограммировании шаблонов, когда вы определяете тип для целей, отличных от определения объектов.

Еще одна вещь, на которую следует обратить внимание: если вы обновили устаревшее приложение, в котором были структуры для использования классов, вы можете столкнуться со следующей проблемой:

В старом коде есть структуры, код был очищен и заменен на классы.Затем в новый обновленный класс была добавлена ​​одна или две виртуальные функции.

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

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

  1. Члены структуры по умолчанию являются общедоступными, члены класса по умолчанию являются закрытыми.
  2. Наследование по умолчанию для структуры из другой структуры или класса является общедоступным. Наследование по умолчанию для класса из другой структуры или класса является частным.
class A{    
public:    
    int i;      
};

class A2:A{    
};

struct A3:A{    
};


struct abc{    
    int i;
};

struct abc2:abc{    
};

class abc3:abc{
};


int _tmain(int argc, _TCHAR* argv[])
{    
    abc2 objabc;
    objabc.i = 10;

    A3 ob;
    ob.i = 10;

    //A2 obja; //privately inherited
    //obja.i = 10;

    //abc3 obss;
    //obss.i = 10;
}

Это на VS2005.

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

template<class T> // OK
template<struct T> // ERROR, struct not allowed here
  1. Член класса, определенного ключевым словом class являются private по умолчанию.Члены класса, определенные ключевыми словами struct (или union) являются public по умолчанию.

  2. При отсутствии спецификатора доступа для базового класса, public предполагается, когда полученный класс объявлен struct и private предполагается, когда класс объявлен class.

  3. Вы можете объявить enum class но не enum struct.

  4. Вы можете использовать template<class T> но нет template<struct T>.

Обратите также внимание, что стандарт C++ позволяет заранее объявлять тип как struct, а затем используйте class при объявлении типа и наоборот.Также, std::is_class<Y>::value является true для Y является struct и class, но это false для enum class.

Вот хорошее объяснение: http://carcino.gen.nz/tech/cpp/struct_vs_class.php

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

Это просто соглашение.Структуры могут быть созданы для хранения простых данных, но со временем они будут развиваться с добавлением функций-членов и конструкторов.С другой стороны, необычно видеть что-то кроме публичного:доступ в структуре.

ИСО МЭК 14882-2003

9 классов

§3

Структура - это класс, определенный с ключ класса struct;Его члены и базовые классы (пункт 10) по умолчанию являются общедоступными (пункт 11).

В других ответах упоминаются частные/публичные значения по умолчанию (но обратите внимание, что структура - это класс, это структура;это не два разных предмета, а просто два способа определения одного и того же предмета).

Что может быть интересно отметить (особенно потому, что спрашивающий, скорее всего, будет использовать MSVC++, поскольку он упоминает «неуправляемый» C++), так это то, что Visual C++ при определенных обстоятельствах жалуется, если класс объявлен с class а затем определяется с помощью struct (или, возможно, наоборот), хотя стандарт гласит, что это совершенно законно.

  • .В классах все участники по умолчанию являются частными, но в структуре участники по умолчанию публично.

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

    2. Размер пустой структуры Sizeof равен 0 байтам, а размер пустого класса Sizeof равен 1 байту. Тип доступа к структуре по умолчанию — общедоступный.Структура обычно должна использоваться для группировки данных.

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

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

    В структурах C ++ и классы передаются по значению, если только явно отказано.В других языках классы и структуры могут иметь особую семантику - т.е.Объекты (экземпляры классов) могут передаваться с помощью ссылки, и структуры могут быть переданы по значению.Примечание:Есть комментарии, связанные с этим вопросом.Смотрите страницу обсуждения, чтобы добавить в разговор.

Хотя это подразумевается в других ответах, это явно не упоминается - структуры совместимы с C, в зависимости от использования;занятия нет.

Это означает, что если вы пишете заголовок, который должен быть совместим с C, у вас нет другого выбора, кроме структуры (которая в мире C не может иметь функций;но может иметь указатели на функции).

Разница между class и struct это разница между ключевыми словами, а не между типами данных.Эти два

struct foo : foo_base { int x;};
class bar : bar_base { int x; };

оба определяют тип класса.Разница между ключевыми словами в этом контексте заключается в разном доступе по умолчанию:

  • foo::x является публичным и foo_base наследуется публично
  • bar::x является частным и bar_base наследуется в частном порядке

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

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

Если вы прочтете некоторые принципы разработки программного обеспечения, вы обнаружите, что большинство стандартов невозможно легко реализовать без классов.например:http://en.wikipedia.org/wiki/SOLID_%28объектно-ориентированный_дизайн%29

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

Вы можете рассмотреть это как рекомендации о том, когда использовать структуру или класс, https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx .

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

X Избегайте определения структуры, если тип не имеет всех следующих характеристик:

Он логически представляет единственное значение, похожее на примитивные типы (int, двойной и т. Д.).

Он имеет размер экземпляра до 16 байт.

Это неизменно.

Это не должно часто быть в штучной упаковке.

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

Из всех этих факторов можно сделать вывод, что концепция класса очень подходит для представления объектов реального мира, а не «структур». Во многом потому, что концепции ООП, используемые в классе, очень практичны при объяснении сценариев реального мира, поэтому их легче объединить с реальностью. Например, наследование по умолчанию является общедоступным для структур, но если мы применим это правило к реальному миру, это смешно. Но в классе наследование по умолчанию является частным, что более реалистично.

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

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

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

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

Например:

Class MyClass
{
    Public Int DataMember;  //By default, accessibility of class data members 
                            //will be private. So I am making it as Public which 
                            //can be accessed outside of the class.
}

В основном методе
Я могу создать экземпляр этого класса, используя новый оператор, который выделяет память для этого класса.
и сохраняет его базовый адрес в переменную типа MyClass (_myClassObject2).

Static Public void Main (string[] arg)
{
    MyClass _myClassObject1 = new MyClass();
    _myClassObject1.DataMember = 10;

    MyClass _myClassObject2 = _myClassObject1;
    _myClassObject2.DataMember=20;
}

В приведенной выше программе MyClass _myClassObject2 = _myClassObject1;инструкция указывает, что обе переменные типа MyClass

  1. мойКлассОбъект1
  2. мойКлассОбъект2

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

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

"_myclassobject1.datamember = 10;" В этой строке оба члена данных объекта будут содержать значение 10.
"_myclassobject2.datamember = 20;" В этой строке оба элемента данных объекта будут содержать значение 20.
В конце концов, мы получаем доступ к элементам данных объекта через указатели.

В отличие от классов, структуры являются типами значений.Например:

Structure MyStructure
{
    Public Int DataMember;  //By default, accessibility of Structure data 
                            //members will be private. So I am making it as 
                            //Public which can be accessed out side of the structure.
}

Static Public void Main (string[] arg)
{
    MyStructure _myStructObject1 = new MyStructure();
    _myStructObject1.DataMember = 10;

    MyStructure _myStructObject2 = _myStructObject1;
    _myStructObject2.DataMember = 20;
}

В приведенной выше программе
создание экземпляра объекта типа MyStructure с использованием нового оператора и
сохранение адреса в переменной _myStructObject типа MyStructure и
присвоение значения 10 элементу данных структуры с использованием «_myStructObject1.DataMember = 10».

В следующей строке
Я объявляю еще одну переменную _myStructObject2 типа MyStructure и присваиваю ей _myStructObject1.
Здесь компилятор .NET C# создает еще одну копию объекта _myStructureObject1 и
присваивает это место памяти переменной MyStructure _myStructObject2.

Поэтому какое бы изменение мы ни внесли в _myStructObject1, оно никогда не повлияет на другую переменную _myStructObject2 типа MyStructrue.
Вот почему мы говорим, что структуры — это типы значений.

Таким образом, непосредственным базовым классом для класса является Object, а непосредственным базовым классом для структуры является ValueType, который наследуется от Object.
Классы будут поддерживать наследование, а структуры — нет.

Как мы это говорим?
И в чем причина этого?
Ответ: Классы.

Он может быть абстрактным, запечатанным, статичным и частичным и не может быть частным, защищенным и защищенным внутренним.

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

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

Но от программиста зависит, какой способ он/она считает подходящим... по моему мнению, я всегда предпочитаю класс только потому, что он поддерживает ООП, и именно поэтому он реализован почти на всех языках, и это замечательная особенность программирования всех времен ;- )

И да, самое незабываемое отличие, которое я забыл упомянуть, заключается в том, что класс поддерживает скрытие данных, а также поддерживает операции, которые выполняются над встроенными типами данных, а структура - нет!

**ОБНОВЛЯТЬ:** Пожалуйста, проигнорируйте этот ответ.Я не учел возможность того, что значение структуры было неинициализировано, а просто оказалось равным 0.Между структурой и классом нет разницы в инициализации.


Я вижу еще одно различие между структурами и классами, связанное с инициализацией по умолчанию.

struct Foo {
    int a;
};

class Bar {
    int a;
};

class Tester {
    Foo m_Foo = Foo();
    Bar m_Bar = Bar();

public:
    Tester() {}
};

int main() {
    auto myTester = Tester();
}

Запустите этот код и проверьте myTester.Вы обнаружите, что для m_Foo структура m_Foo.a инициализирована значением 0, но для m_Bar класс m_Bar.a не инициализирован.Таким образом, похоже, существует разница в том, что делает конструктор по умолчанию для struct и struct.сорт.Я вижу это с Visual Studio.

Есть 3 основных различия между структурой и классом

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

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

3Rd- нельзя повторно использовать код в структуре, но в классе мы можем повторно использовать один и тот же код много раз, что называется наследственностью.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top