C++ и Swift: как обрабатываются структуры в фреймах стека C++? Являются ли сложности структурного наследования, почему Swift не поддерживает структурное наследование?
У недавнего разработчика встретиться с темой struct
наследование в Свифте (точнее отсутствие struct
наследство в Swift) было кратко обсуждено. Я предположил, что причина, по которой Swift не поддерживает struct
наследование потому что:
struct
s являются типами значений- типы значений копируются между кадрами стека
- наследование будет означать, что размер
struct
может варьироваться (например, еслиLorry
наследуется отVehicle
а такжеLorry
добавляет.weightCapacity
затемLorry
потребуется больше места, чемVehicle
) - Наличие параметров типа значения с размером, который не известен во время компиляции, усложнит построение стекового фрейма для вызывающей стороны и доступ к данным для вызываемой
Я предполагаю, что это из-за этих сложностей, которые предположительно добавили бы дополнительные операции к каждому вызову функции, который включает struct
и, таким образом, ухудшить производительность, что Swift не позволяет struct
наследование. Это рассуждение правильно?
Но тогда я подумал о C++. C++ позволяет struct
наследование и C++ очень ориентированы на производительность. Это заставляет меня думать, что мои рассуждения о Свифте не позволяют struct
наследование это неправильно. Как достигается C++ struct
наследование без негативного влияния на производительность?
2 ответа
Как в C++ достигается структурное наследование без негативного влияния на производительность?
В C++ компилятор всегда знает размер struct
, Но когда базовый класс копируется по значению, объект "разрезается": копируются только члены базового класса, и новый объект никоим образом не связан с производным классом исходного объекта.
Так что если функция хочет сделать что-то с Vehicle
без выделения его дополнительной идентичности, он должен использовать указатель или ссылку на Vehicle
как тип параметра функции или тип возвращаемого значения. Но в этот момент у вас больше нет "типов значений, скопированных между кадрами стека".
Поскольку структуры являются типами значений, вы должны скопировать их в функцию и обратно. Таким образом, вы могли бы вызвать не мутантный метод с производной структурой, но не смогли бы вернуть производное значение из него, поэтому
struct Vehicle {
var color: Color
mutating func paintWhite() {
self.color = .White
}
}
struct Lorry: Vehicle ...
var lorry = Lorry(color:.Blue)
lorry.paintWhite() // <- wouldn't work, as paintWhite takes inout Vehicle
Без возможности вызывать изменяющие методы структуры были бы гораздо менее полезными и намного более запутанными.