Каковы различия между структурой и классом в C ++? - PullRequest
413 голосов
/ 18 сентября 2008

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

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

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

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

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

Ответы [ 29 ]

449 голосов
/ 16 июня 2009

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

Четвертый стандарт (§11.2.2 в C ++ 98 - C ++ 11):

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

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

Член класса, определенного с ключевое слово класс является личным дефолт. Члены определенного класса с ключевыми словами struct или union public по умолчанию.

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

157 голосов
/ 18 сентября 2008

Цитирование FAQ по C ++ ,

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

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

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

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

115 голосов
/ 08 августа 2010

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

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

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

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

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

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

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

31 голосов
/ 18 сентября 2008

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

28 голосов
/ 18 сентября 2008

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

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

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

9 голосов
/ 24 июля 2015

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;
}
9 голосов
/ 18 сентября 2008

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

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

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

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

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

8 голосов
/ 18 сентября 2008

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

4 голосов
/ 19 сентября 2008
  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.

4 голосов
/ 18 сентября 2008

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

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

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

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

...