Поместить данные в объявление класса?

В один из часто задаваемых вопросов Страуструпа, он приводит следующий пример:

template<class Scalar> class complex {
public:
complex() : re(0), im(0) { }
complex(Scalar r) : re(r), im(0) { }
complex(Scalar r, Scalar i) : re(r), im(i) { }
// ...

complex& operator+=(const complex& a)
{ re+=a.re; im+=a.im; return *this; }
// ...
private:
Scalar re, im;
};

и описывает:

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

Может ли кто-нибудь помочь объяснить это? Положил re, im данные в объявлении класса заставляют объект класса размещаться в стеке? А как насчет встраивания? (Я вижу operator+= встроенный, он имеет в виду это?)

3

Решение

Помещение данных в определение класса не делает объект
выделить на стеке, но это позволяет. В том месте, где объект
определено, компилятор должен знать его полный размер; если объект
определиться в стеке, компилятор должен знать его размер в
единица перевода, которая определяет это.

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

Аналогично, встроенная функция может манипулировать только теми данными, которые она видит.

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

1

Другие решения

Участники re а также im распределяются внутри каждого complex объект. Это означает, что re а также im расположены в стеке если и только если целый complex Объект есть. Если complex объект является глобальным, то re а также im ни в стеке, ни в куче.

На практике компиляторы будут ставить re по смещению 0 в объекте и im по смещению sizeof(Scalar), Это означает, что код для operator+= не нужно много инструкций по сборке, чтобы получить эти элементы. Сами фактические дополнения, вероятно, являются всего лишь двумя инструкциями по сборке, поэтому загрузка 4 элементов и сохранение двух результатов — это основная часть работы. И встраивание работает лучше всего, если есть мало для встраивания.

3

Это конкретный класс, который не предназначен для получения (потому что в этом нет необходимости).

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

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

Я не думаю, что здесь есть что-то волшебное, это всего лишь пример того, где уместно использовать класс «тип значения».

3
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector