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

441

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

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

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

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

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

palm3D
источник
6
Эта ссылка хорошо суммирует различия.
sjsam
1
Почему тогда все люди используют struct для построения дерева? Потому что, похоже, разница не так уж и велика. Кстати, что это отличный сайт @ sjsam.
JW.ZG
1
Ищете разницу между structC и C ++? Смотрите здесь .
23
@ JW.ZG Не "все" люди делают! Те, кто это делает, либо просто предпочитают, либо не понимают, что structозначает C ++. ;) Но нет причины, по которой вы не можете использовать это classключевое слово.
Гонки

Ответы:

466

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

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

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

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

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

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

Ассаф Лави
источник
22
Это на самом деле не второе отличие, просто вопрос задал разницу не полностью. Все подобъекты являются закрытыми по умолчанию при использовании class, public по умолчанию с struct, и оба определяют тип класса.
Бен Фойгт
10
Я думаю, ты упустил суть, Бен. Это наследие, которое является общедоступным для структур и частным для классов. Это очень важное различие, и оно совершенно не связано с фактическим доступом членов. Например, язык вполне мог бы определить его иначе, например, оба публично наследуются по умолчанию, и вы получите очень разные значения.
Ассаф Лави
104
На самом деле, настоящая хитрая разница между structи classзаключается в том, что последний может использоваться вместо a typenameдля объявления параметра шаблона, а первый - нет. :)
sbi
21
@MrUniverse: это совершенно неправильно. (Есть школа, которая использует это для соглашения, но это не соблюдается синтаксически.)
sbi
3
@sbi «реальная хитрая разница между структурой и классом» - Милым, но вопросом о разнице между в структуры и в классе, а не о различиях в котором ключевых слова могут быть использованы.
Джим Балтер
161

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

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

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

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

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

Robᵩ
источник
123

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

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

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

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

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

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

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

Джон Ханна
источник
Вероятно, также стоит отметить, что, вероятно, было проще, чтобы классы и структуры работали одинаково под капотом, чем иметь их принципиально иными. Оглядываясь назад, можно было бы получить определенную выгоду, например, указав, что все, что объявлено как структура, должно быть PODS (то есть запрещать структурам иметь виртуальные члены, нетривиальные конструкторы по умолчанию или деструкторы и т. Д.), Но мне это не известно когда-либо требовалось ни стандартом C ++, ни реализацией.
суперкат
1
@supercat тот факт, что это был ОО-язык, в котором обширный набор программ, написанных на не-ОО-языке, являлся действительными программами, выдвинул концепцию на передний план, и, похоже, он подходит больше, чем в более чисто ОО-языках. (и, конечно, фактически определено в стандарте). История раннего C ++ определенно многое объясняет. Страуструп "Дизайн и эволюция C ++" - интересное чтение.
Джон Ханна
1
Я воспринимаю религиозную войну между людьми , которые считают , что все , что не является «OOP-иш», должно быть, и те , кто думает , что ООП следует рассматривать как на инструмент, но не на инструмент. C ++ определенно охватывает последнюю философию, но я действительно мало знаю о языках до этого. Моя собственная философия заключается в том, что когда кто-то хочет объект, он должен использовать объект, а когда кто-то хочет объединить связанные, но независимые переменные, он должен использовать это. C ++ не проводит никаких синтаксических различий между такими вещами, и .NET пытается стереть это различие, но мало что я знаю о D ...
суперкат
1
... предполагает, что он распознает это больше, чем C ++ или .NET. Агрегирование переменных не совсем OOPish, но это не значит, что их не следует использовать, когда они полезны .
суперкат
3
Я не согласен с тем, что «C имеет структуры, у него нет понятия инкапсуляции, поэтому все является открытым». Вы можете скрыть определение structвнутреннего *.c-файла и позволить другим модулям перевода использовать его только с указателем. Таким образом, у вас есть еще более сильная инкапсуляция, потому что другие единицы перевода даже не знают, что находится внутри struct.
12431234123412341234123
32

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

Kasprzol
источник
15
Не только участники, но и весь доступ, включая наследование.
Неманя Трифунович
4
Ну, я бы сказал, что другое отличие - это семантика. Структура многих людей заставляет их думать о «структуре данных» как о пережитке С.
Крис Кумлер,
3
@KrisKumler: Это не "семантика"; это личные чувства. И то structи другое classобъявляет класс с идентичной семантикой (несмотря на синтаксическую интерпретацию тела определения).
Гонки легкости на орбите
28

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

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

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

crashmstr
источник
32
Какая разница? Пожалуйста, объясни.
crashmstr
10

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

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

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

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

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

64BitBob
источник
1
Это самая неочевидная вещь в структурах и классах. «Структуры - это данные, классы - это код», можно перефразировать так: «Структуры - это данные, классы - это данные, безопасность и операции, выполняемые с этими данными»
Арун Аравинд,
3
Невозможно создать структуру в C ++. Создать класс можно только с использованием унаследованного structключевого слова.
Гонки Лёгкости на орбите
1
Этот ответ, похоже, не о C ++. В C ++ structобъявляет классы (включая public/ private/ protected, наследование и т. Д.).
Мельпомена
Как структуры являются абстрактными? Запись необработанных структур в файл чревата проблемами даже в C (обычные проблемы включают заполнение, порядковый номер, разный размер слова и т. Д.). Что это за SIZEмакрос, о котором ты говоришь?
Мельпомена
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;
}
Сурадж К Томас
источник
Я удалил примеры кода 3-7, как было упомянуто экспертами
Suraj K Thomas
8

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

Skizz
источник
5
  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.

Мельпомена
источник
_tmainне является стандартным C ++.
Мельпомена
4

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

MSalters
источник
4

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

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

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

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

KPexEA
источник
1
Код, который использует memfill для очистки структуры, вероятно, имеет другие оскорбительные привычки. Иди с осторожностью.
Дэвид Торнли
@DavidThornley: Использование нулевой заливки для стирания или инициализации структуры данных является стандартным в C. В проекте со смешанным языком нельзя ожидать, что код в части C будет избегаться callocв пользу new. Все, что можно сделать, - это убедиться, что любые структуры, используемые частью кода C, на самом деле являются PODS.
суперкат
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.

Вирсавия
источник
хороший ответ, хотя мне не хватает четкого безошибочного 0) разница между structи classв c ++ - это разница между ключевыми словами, а не между типами данных (или какой-то лучшей альтернативой;)
idclev 463035818
@ прежние известные_463035818: Но вы не думаете, что это std::is_class<Y>::valueпокрывает?
Вирсавия
да, просто подумал, что это может быть более заметным, потому что это распространенное недоразумение, а остальное - просто следствия.
idclev 463035818
Неважно, твой ответ идеален, как и я, я написал еще один, не больно иметь еще один
idclev 463035818
4

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

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

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

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

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

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

nutario
источник
2

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

finnw
источник
2

ISO IEC 14882-2003

9 классов

§ 3

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

Григорий Пакош
источник
2

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

template<class T> // OK
template<struct T> // ERROR, struct not allowed here
Стефан Попеску
источник
1
Если вы намеревались подчеркнуть, что структуры нельзя использовать как обобщенные типы, то вы ошибаетесь. И structне допускается там просто соглашением (лучше сказать, что это classключевое слово, которое используется в другом смысле здесь, см. Использование 'class' или 'typename' для параметров шаблона ).
dma_k
Ключевое слово там не разрешено, но вы можете передать класс, который вы определили, structпросто отлично. Просто попробуйте. struct T{}; template <typename T> void foo() {} foo<T>();
Гонки
1

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

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

ymett
источник
Я знаю, что это очень поздний комментарий, но имейте в виду, что вышеупомянутое предупреждение не лишено достоинств, поскольку Windows ABI по-разному манипулирует структурами и классами, и поэтому смешанные (прямые) объявления класса и структуры могут фактически привести к трудностям в понимании проблем со связыванием!
MFH
1
  • , В классах все члены по умолчанию являются закрытыми, но в структуре члены являются открытыми по умолчанию.

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

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

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

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

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

yshivakathik
источник
3
Msgstr "Размер пустой структуры равен 0 байтам, поскольку размер пустого класса равен 1 байту". Ложь. Я только что проверил с g++. Возможно, вы думаете об Оптимизации пустой базы, но это относится и к обоим.
cdunn2001
1
Не правда. В C ++ размер пустой структуры равен 1. В C пустая структура не допускается. GCC допускает пустые структуры в C как расширение компилятора, и такая структура имеет размер 0.
Johan Råde
Этот ответ неверен. В дополнение к размеру, часть конструктор / деструктор также неточна: структуры могут иметь конструкторы и деструкторы очень хорошо. Фактически structсоздает полноценные классы в C ++.
Мельпомена
1

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

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

UKMonkey
источник
-1

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

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

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

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

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

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

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

kiriloff
источник
Это касается .NET / C #, а не C ++.
Мельпомена
-2

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

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

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

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

снег
источник
Этот ответ, похоже, не о C ++. В C ++ structобъявляет классы (включая управление разрешениями, наследование и т. Д.).
Мельпомена
-3

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

MOBITI MAHENGE
источник
ОП уже упоминал, что structчлены по умолчанию являются публичными, а в принятом ответе от 2009 года упоминается наследование. Зачем писать еще один ответ, который не добавляет новой информации через 4 года?
Мельпомена
-3

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

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

Wageesha
источник
1
Как частное наследство "более реалистично"? Большинство языков программирования даже не имеют понятия частного наследования.
Мельпомена
-3

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

Тушар Бобаде
источник
Этот ответ, похоже, не о C ++. В C ++ structобъявляет классы (включая public/ private/ protected, наследование и т. Д.).
Мельпомена
-3

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

Эрик Хилл
источник
1
Как вы определили, что m_Foo.aбыло инициализировано? Что, если он был неинициализирован и просто оказался 0?
Мельпомена
Ухххххххххххх Виноват. Это не разница между структурой и классом. Характеристики инициализации одинаковы.
Эрик Хилл
-4

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

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

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

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

Юг Равал
источник
1
В C ++ structмогут быть функции-члены
chtz
@chtz Спасибо ... я узнал об этой функции только сейчас .. большое спасибо .. я просто новичок, не такой опытный, как вы, так что в будущем также нужны советы от вас, ребята :-)
Yug
и на самом деле, функция-член должна быть предназначена в более широком смысле. structможет иметь конструкторы, функцию-член и распределитель (возможно, виртуальный, возможно частный, защищенный или общедоступный). Они могут наследовать и наследоваться. так на самом деле ... все, что может иметь класс. Типичное соглашение - объявлять через struct то, что вы бы объявили как struct в C и как класс, если мы объявим приватную и защищенную переменную, виртуальные функции, ctor и dtor и так далее. Но это просто соглашение, не соблюдаемое языком
Джан Паоло
-5

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

Али
источник
4
Это неправда. В этом отношении нет никакой разницы между классом, определенным с structключевым словом, и классом, определенным с classключевым словом.
Ymett
когда я использую структуру без конструктора, я получаю лучшую скорость, чем класс без конструктора.
Али
@ Али Нет, нет.
Гонки
-5

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

Например:

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.
Классы будут поддерживать наследование, а структуры - нет.

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

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

Абхишек Шарма
источник
4
Я думаю, что это пытается ответить на вопрос для C #? Вопрос о c ++, и это делает этот ответ неточным, верно?
smw
@smw абсолютно, он написал свой пример кода на C #, и я пришел сюда, чтобы проверить, не было ли различий в передаче параметров между C ++ structи class. Никто здесь не упомянул об этом, ни весь веб. Так что я не думаю, что это относится и к C ++.
Джон
Это даже не правильный код C # - все ключевые слова неверны. «Public», «Static», «Int» и «Class» не должны начинаться с заглавной буквы и должны быть «struct», а не «Structure». Описание в основном верно для C # (хотя структуры все еще могут наследовать интерфейсы, но не другие структуры), но не отвечают на вопрос, поскольку речь шла о C ++ ...
Даррел Хоффман
2
Этот ответ полная чушь. Он использует странное сочетание Visual Basic и C # для своих примеров кода, и весь «Классы являются ссылочными типами, а структуры являются типами значений» ... вещь относится только к .NET (т.е. C #), но не к C ++. Ты не в той комнате, чувак. Вот где вы находитесь: stackoverflow.com/questions/13049
TheFlash
Но этот ответ указывает, что то же самое верно для C (++), что структуры используются как типы значений. int a = 3; int b = a;и тому подобноеMyStruct a=MyStruct("data"); MyStruct b = a;
везение
-8

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

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

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

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

Нэвин
источник
2
Структуры C ++ поддерживают наследование и абстрактные методы. Структура и класс расположены одинаково. Распределение классов в куче, даже если они не созданы с помощью «нового», не имеет смысла для встроенных систем.
JCMS
2
№ 1 тоже не так. Стек используется, когда вы объявляете что-то такого типа как локальную переменную, а куча используется, когда вы используете оператор «new».
Score_Under