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

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

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

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

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

Я уверен, что существуют другие отличия в неясных углах спецификации С++.

Ответ 1

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

Укажите стандарт (§11.2.2 в С++ 98 - С++ 11):

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

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

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

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

Ответ 2

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

[7.8] Какая разница между ключевые слова struct и class?

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

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

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

Ответ 3

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

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

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

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

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

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

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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

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

По сути, структуры относятся к данным, классы относятся к коду.

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

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

Ответ 10

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

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

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

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

Ответ 11

  • Члены структуры являются общедоступными по умолчанию, члены класса являются закрытыми по умолчанию.
  • Наследование по умолчанию для структуры из другой структуры или класса является public.Default наследование для класса из другой структуры или класса является закрытым.
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.

Ответ 12

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

template<class T> // OK
template<struct T> // ERROR, struct not allowed here

Ответ 13

  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.

Ответ 14

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

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

Ответ 15

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

Ответ 16

ISO IEC 14882-2003

9 Классы

§ 3

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

Ответ 17

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

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

Ответ 18

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

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

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

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

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

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

Ответ 19

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

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

Ответ 20

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

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

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

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

Ответ 21

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

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

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

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

Ответ 22

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

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

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

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

У него есть экземпляр размер до 16 байтов.

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

Он не должен быть в коробке часто.

Ответ 23

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

Ответ 24

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

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

Ответ 25

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

Ответ 26

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

Ответ 27

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

Например:

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

  •   
  • myClassObject1  
  • 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 с использованием нового оператора и
сохранение адреса в переменной _myStructObject типа MyStructure и
присваивая значение 10 элементу данных структуры, используя "_myStructObject1.DataMember = 10".

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

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

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

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

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

Ответ 28

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

Ответ 29

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

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

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

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

Ответ 30

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

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

2Nd. По умолчанию структура рассматривается как публикация, рассматриваемая классом как частная.

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