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

c++ oop class struct c++-faq

336196 просмотра

30 ответа

Этот вопрос уже задавался в контексте C # /. Net .

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

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

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

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

Автор: palm3D Источник Размещён: 11.11.2019 05:17

Ответы (30)


456 плюса

Решение

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

Quoth стандарт (§11.2.2 в C ++ 98 до C ++ 11):

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

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

Член класса, определенного с помощью ключевого слова class , по умолчанию является закрытым . Члены класса, определенного с помощью ключевых слов struct или union, являются открытыми по умолчанию.

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

Автор: Assaf Lavie Размещён: 16.06.2009 06:19

160 плюса

Цитируя C ++ FAQ ,

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

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

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

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

Автор: Robᵩ Размещён: 18.09.2008 02:18

121 плюса

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

C имеет структуры, у него нет концепции инкапсуляции, поэтому все открыто.

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

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

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

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

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

Автор: Jon Hanna Размещён: 07.08.2010 11:17

31 плюса

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

Автор: Kasprzol Размещён: 18.09.2008 02:12

27 плюса

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

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

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

Автор: crashmstr Размещён: 18.09.2008 02:15

10 плюса

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

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

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

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

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

Автор: 64BitBob Размещён: 18.09.2008 02:23

10 плюса

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;
}
Автор: Suraj K Thomas Размещён: 24.07.2015 05:44

8 плюса

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

Автор: Skizz Размещён: 18.09.2008 02:15

4 плюса

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

Автор: MSalters Размещён: 18.09.2008 02:15

4 плюса

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

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

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

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

Автор: KPexEA Размещён: 18.09.2008 03:31

4 плюса

  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.

Автор: GirishNayak Размещён: 19.09.2008 10:12

4 плюса

  1. Член класса, определенного с ключевым словом class, privateпо умолчанию. Члены класса, определенного с помощью ключевых слов struct(или union), являются publicпо умолчанию.

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

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

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

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

Автор: Bathsheba Размещён: 19.12.2018 02:00

3 плюса

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

template<class T> // OK
template<struct T> // ERROR, struct not allowed here
Автор: Stefan Popescu Размещён: 12.11.2011 11:21

2 плюса

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

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

Автор: nutario Размещён: 18.09.2008 02:13

2 плюса

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

Автор: finnw Размещён: 18.09.2008 02:17

2 плюса

ISO IEC 14882-2003

9 классов

§ 3

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

Автор: Gregory Pakosz Размещён: 18.04.2010 09:18

1 плюс

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

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

Автор: ymett Размещён: 04.08.2011 02:25

1 плюс

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

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

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

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

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

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

Автор: yshivakathik Размещён: 10.07.2012 07:07

1 плюс

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

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

Автор: UKMonkey Размещён: 29.09.2016 11:38

1 плюс

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

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

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

  • foo::xявляется публичным и foo_baseнаследуется публично
  • bar::xявляется частным и bar_baseнаследуется в частном порядке
Автор: formerlyknownas_463035818 Размещён: 19.06.2019 08:35

-1 плюса

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

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

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

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

Автор: snow Размещён: 16.03.2015 04:49

-1 плюса

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

√ РАССМОТРИТЕ определение структуры вместо класса, если экземпляры типа маленькие и обычно недолговечные или обычно встроены в другие объекты.

X ИЗБЕГАЙТЕ определения структуры, если тип не имеет всех следующих характеристик:

Логически представляет одно значение, подобное примитивным типам (int, double и т. Д.).

Размер экземпляра не превышает 16 байт.

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

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

Автор: kiriloff Размещён: 01.05.2015 12:30

-2 плюса

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

Автор: MOBITI MAHENGE Размещён: 15.04.2013 01:57

-2 плюса

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

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

Автор: Wageesha Размещён: 27.08.2013 01:22

-3 плюса

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

Автор: Tushar Bobade Размещён: 28.01.2014 07:50

-4 плюса

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

Автор: Ali Размещён: 04.08.2011 01:28

-4 плюса

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

Например:

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

В методе main
я могу создать экземпляр этого класса, используя оператор new, который выделяет память для этого класса
и сохраняет его базовый адрес в переменной типа 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. myClassObject1
  2. myClassObject2

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

Поэтому, если какие-либо изменения, которые мы вносим в один из объектов типа 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 с использованием оператора new и
сохранение адреса в переменной _myStructObject типа MyStructure и
присвоение значения 10 члену данных структуры с использованием «_myStructObject1.DataMember = 10».

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

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

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

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

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

Автор: Abhishek Sharma Размещён: 25.09.2013 10:54

-4 плюса

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

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

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

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

Автор: Yug Rawal Размещён: 09.06.2017 01:14

-4 плюса

** ОБНОВЛЕНИЕ: ** Пожалуйста, игнорируйте этот ответ. Я не рассматривал возможность того, что для структуры значение было неинициализировано, а просто оказалось равным 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 неинициализирован. Таким образом, кажется, есть разница в том, что конструктор по умолчанию делает для структуры против класса. Я вижу это с Visual Studio.

Автор: Eric Hill Размещён: 15.07.2015 06:21

-8 плюса

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

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

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

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

Автор: Naveen Размещён: 05.12.2014 02:45
32x32