Когда структуры лучше, чем классы? [дубликат]

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

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

Лучше для создания автомата обоим проверяют считанную структуру (байт на байт) от HD допустимо, и заполнение структуры в оперативной памяти, если это действительно в порядке. Можно освободить некоторые миллисекунды (не так, поскольку это может казаться для современных Ose, делают большое кэширование чтения с диска), хотя Вы получаете независимость компилятора и платформа. Плюс, Ваш код будет легко портирован на другой язык.

Постредактирование: В некотором роде я сочувствую Вам. В хорошие-ol' дни DOS/Win3.11 я когда-то создал программу C для чтения файлов BMP. И используемый точно та же техника. Все было хорошо, пока я не пытался скомпилировать его для Windows - ой!! Интервал был теперь 32 бита длиной, а не 16! То, когда я пытался скомпилировать на Linux, обнаружило, что gcc имел совсем другие правила для выделения битовых полей, чем Microsoft C (6.0!). Я должен был обратиться к макро-приемам для создания его портативным...

14
задан Uwe Keim 16 August 2017 в 07:27
поделиться

7 ответов

Another difference with classes is that when you assign an structure instance to a variable, you are not just copying a reference but indeed copying the whole structure. So if you modify one of the instances (you shouldn't anyway, since structure instances are intended to be immutable), the other one is not modified.

3
ответ дан 1 December 2019 в 09:32
поделиться

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

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

Однако структуры иногда лучше , если:

  • Вам нужен точный контроль над объемом используемой памяти (структуры используют (в зависимости от размера) немного, чтобы НАМНОГО меньше памяти, чем объекты.
  • Вам нужен точный контроль разметки памяти. Это особенно важно для взаимодействия с Win32 или другими собственными API
  • . Вам нужна максимально высокая скорость. (Во многих сценариях с большими наборами данных вы можете получить приличное ускорение при правильном использовании структур.)
  • Вам нужно тратить меньше памяти и иметь большие объемы структурированных данных в массивах. Особенно в сочетании с массивами вы можете получить огромную экономию памяти с помощью структур.
  • Вы много работаете с указателями. Затем структуры предлагают множество интересных характеристик.
12
ответ дан 1 December 2019 в 09:32
поделиться

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

struct Aggregate1
{
    int A;
}

struct Aggregate2
{
    Aggregate1 A;
    Aggregate1 B;
}

Обратите внимание, если бы Aggregate1 был классом, вам пришлось бы инициализировать поля в Aggregate2 вручную ...

Aggregate2 ag2 = new Aggregate2();
ag2.A = new Aggregate1();
ag2.B = new Aggregate1();

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

1
ответ дан 1 December 2019 в 09:32
поделиться

There have been some excellent answers that touch on the practicality of using structs vs. classes and visa-versa, but I think your original comment about structs being immutable is a pretty good argument for why classes are used more often in the high-level design of LOB applications.

In Domain Driven Design http://www.infoq.com/minibooks/domain-driven-design-quickly there is somewhat of a parallel between Entities/Classes and Value Objects/Structs. Entities in DDD are items within the business domain whose identity we need to track with an identifier, e.g. CustomerId, ProductId, etc. Value Objects are items whose values we might be interested in, but whose identity we don't track with an identifier e.g Price or OrderDate. Entities are mutable in DDD except for their Identity Field, while Value Objects do not have an identity.

So when modeling a typical business entity, a class is usually designed along with an identity attribute, which tracks the identity of the business object round trip from the persistance store and back again. Although at runtime we might change all the property values on a business object instance, the entity's identity is retained as long as the identifier is immutable. With business concepts that correspond to Money or Time, a struct is sort of a natural fit because even though a new instance is created whenever we perform a computation, that's ok because we aren't tracking an identity, only storing a value.

0
ответ дан 1 December 2019 в 09:32
поделиться

IMO the most important use case are large arrays of small composite entities. Imagine an array containing 10^6 complex numbers. Or a 2d array containing 1000x1000 24-bit RGB values. Using struct instead of classes can make a huge difference in cases like these.

EDIT: To clarify: Assume you have a struct

struct RGB 
{
   public byte R,G,B;
}

If you declare an array of 1000x1000 RGB values, this array will take exactly 3 MB of memory, because the values types are stored inline.

If you used a class instead of a struct, the array would contain 1000000 references. That alone would take 4 or 8 MB (on a 64 bit machine) of memory. If you initialized all items with separate objects, so you can modify the values separately, you'd habe 1000000 objects swirling around on the managed heap to keep the GC busy. Each object has an overhead (IIRC) of 2 references, i.e. the objects would use 11/19 MB of memory. In total that's 5 times as much memory as the simple struct version.

8
ответ дан 1 December 2019 в 09:32
поделиться

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

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

6
ответ дан 1 December 2019 в 09:32
поделиться

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

-3
ответ дан 1 December 2019 в 09:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: