C++: устранение неоднозначности: подобъект и подкласс
В основном то, что говорит название. Я имел в виду базовые объекты как подобъекты. Это правильно, и будет ли правильно, что subobject
== superclass object
? Какой из них предпочтительнее?
subclass
означает производный класс и subclass object
означает объект производного класса, верно?
Путаница для меня заключается в том, что subclass object
знак равно subobject
,
Если что-то из этого верно, во всяком случае..
Спасибо
5 ответов
Стандарт C++ имеет четкое определение того, что такое подобъект. Тем не менее, многие люди не (точно) используют язык стандарта, когда говорят о C++. Одним из популярных примеров является термин объект. Из таких языков, как Java, некоторые люди склонны использовать объект только в смысле экземпляра класса, который не применим к int
, С точки зрения стандарта C++, int
это объект.
Что Стандарт говорит в [intro.object]/2:
Объекты могут содержать другие объекты, называемые подобъектами. Субобъект может быть подобъектом-членом, подобъектомбазового класса или элементом массива. Объект, который не является подобъектом любого другого объекта, называется законченным объектом.
Это следует понимать в контексте (возможной) схемы памяти. Он не указан полностью, но, скорее всего, выглядит так:
class Foo { int i; };
class Bar : public Foo { int j; };
Объект типа Bar
может выглядеть так в памяти:
+ -Бар -------------------+ | +-Foo-----+ | | | Int I | int j; | | +---------+ | +-----------------------+
То есть члены Foo
являются членами Bar
как прямые члены Bar
, Каждый объект Bar
поэтому "содержит" объект типа Foo
, Также рассмотрим
Bar b;
Bar* pBar = &b;
Foo* pFoo = &b;
+ -Бар -------------------+ | +-Foo-----+ | | | Int I | int j; | | + --------- + | + - ^--------------------+ ^ |pFoo | пбар
Позволять pFoo
указать на завершенные объекты типа Foo
и подобъектам типа Foo
должен существовать целый и (по памяти) независимый объект типа Foo
внутри любого объекта типа Bar
, Во время компиляции может быть неизвестно, какой именно, но код, созданный для pFoo->i = 5;
должен работать для обоих.
Это все определено в соответствии с правилом "как будто", то есть это не должно быть так, но оно должно вести себя так же. Кроме того, не требуется, чтобы это было фактическое расположение памяти, но это - общая реализация.
В [intro.object]/4
Если законченный объект, элемент данных или элемент массива имеют тип класса, его тип считается наиболее производным классом, чтобы отличать его от типа класса любого подобъекта базового класса; объект наиболее производного типа класса или не относящегося к классу типа называется наиболее производным объектом.
В стандарте нет смысла использовать слово super, кроме supersede и superset. Там есть базовый класс и производный класс (а также ~ объект).
Вне стандарта языка C++ термин суперкласс используется для ссылки на базовый класс, а термин подкласс используется для ссылки на производный класс. Это относится к концепциям и классификации ОО, так же как вид является подкатегорией рода в биологии.
Но в этой категории нет разметки памяти, поэтому нет необходимости говорить о подобъектах. Существуют экземпляры или объекты (в смысле ОО) классов, так что вы можете говорить об объектах суперкласса и объектах подкласса. Путаница может быть вызвана сокращением этого объекта подкласса до подобъекта и смешением языка ОО с языком из стандарта С ++.
Это радует, когда общие объектно-ориентированные термины смешиваются с терминами, связанными с C++.
- подобъект: Любой объект, который хранится в другом объекте (элементы массива, объекты базового класса и объекты-члены данных).
- подкласс: общий термин ориентации объекта, относящийся к тому, что в C++ называется "производным классом"
- суперкласс: общий термин ориентации объекта, относящийся к тому, что в C++ называется "базовым классом".
- завершенный объект: любой объект, который не хранится в другом объекте.
Небольшая подсказка - когда я говорю на земле C++, я пытаюсь использовать терминологию C++. Когда я говорю на земле Java, я пытаюсь говорить с терминологией Java.
Подобъект - это терминология C++ для объекта, который является частью другого объекта; либо член, либо базовый класс.
Подкласс - это терминология, используемая в других языках, и более общее обсуждение наследования для обозначения производного класса. Это происходит из-за соглашения рисования иерархий классов в виде перевернутых деревьев с корнем вверху. C++ не использует этот термин, возможно, из-за потенциальной путаницы, которую вы описываете.
Чтобы избежать путаницы при обсуждении наследования в C++, используйте стандартную терминологию базовых и производных классов.
Я думаю, что чаще всего подобъект смущает ссылки на связанные с базовым классом части объекта подкласса (например, некоторые указатели vtable), особенно в условиях, когда задействовано множественное наследование. Я бы рекомендовал избегать этого термина и придерживаться более устойчивой терминологии (Super/Sub, Base/Derived).