Виртуальные элементы данных базового класса

Вы можете попробовать fit-content (CSS3):

div {
  width: fit-content; 
  /* To adjust the height as well */ 
  height: fit-content;
}

8
задан jackhab 28 July 2009 в 10:27
поделиться

5 ответов

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

Самый большой недостаток виртуального наследования - это то, что их конструкторы принимают параметры. Если вам нужно передать параметры конструктору виртуального базового класса, вы заставляете все производные классы явно вызывать конструктор (они не могут полагаться на базовый класс, вызывающий конструктор). Я сделал домашнюю работу после комментария Мартина, спасибо Марин. Первая строка не совсем верна:

На практике вы должны использовать только виртуальное наследование для определения интерфейсы, как они обычно используются с множественным наследованием для обеспечения что только одна версия класса присутствует в производном классе.

Виртуальное наследование не имеет значения, если базовый класс является чистым интерфейсом (за исключением немного других ошибок компилятора в vc8, если не все методы реализованы). Это имеет значение только в том случае, если в базовом классе есть данные, в этом случае вы получите ромб, а не U-образную форму

Non virtual    virtual
  A     A          A
  |     |        /   \
  B     C       B     C
   \   /         \   /
     D             D

В виртуальном случае B и C используют одну и ту же копию A.

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

11
ответ дан 5 December 2019 в 12:11
поделиться

Основной совет - иметь конструктор по умолчанию в виртуальной базе. Если вы этого не сделаете, то каждый наиболее производный класс (т.е. любой подкласс) должен явно вызывать виртуальный базовый ctor, и это приводит к тому, что разгневанные коллеги стучатся в дверь вашего офиса ...

class VirtualBase {
public:
    explicit VirtualBase( int i ) : m_i( i ) {}
    virtual ~VirtualBase() {}

private:
    int m_i;
};

class Derived : public virtual VirtualBase {
public:
    Derived() : VirtualBase( 0 ) {} // ok, this is to be expected
};

class DerivedDerived : public Derived { // no VirtualBase visible
public:
    DerivedDerived() : Derived() {} // ok? no: error: need to explicitly
                                    // call VirtualBase::VirtualBase!!
    DerivedDerived() : VirtualBase( 0 ), Derived() {} // ok
};
2
ответ дан 5 December 2019 в 12:11
поделиться

a) члены должны быть закрытыми - поэтому у вас могут возникнуть проблемы с их использованием в производных классах (поэтому вам нужно добавить методы получения и установки, которые взорвут ваш интерфейс)

b) не объявляйте то, что вы в настоящее время не объявляете use - объявлять переменные только в классах, которые имеют к ним доступ / используют

c) виртуальные базовые классы должны содержать только интерфейсы / виртуальные методы, не более того

Я надеюсь, что это немного поможет, даже если мои причины не идеальны и завершено :)

ciao, Крис

0
ответ дан 5 December 2019 в 12:11
поделиться

Я никогда не видел этой рекомендации.

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

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

1
ответ дан 5 December 2019 в 12:11
поделиться

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

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

  • сделайте их максимально скрытыми и используйте геттеры и сеттеры, если вам нужно сохранить инварианты классов.
    (Здесь есть лазейка: если с членом не связан инвариант, т.е. он может принимать любое возможное значение в любой момент времени, вы можете сделать его общедоступным. Однако это отрицает добавление инварианта производным классом.
  • Дизайн для наследование: контракт вашего класса должен определять обязанности и возможности производного класса, что ему нужно / можно перезаписать с какой целью.
0
ответ дан 5 December 2019 в 12:11
поделиться
Другие вопросы по тегам:

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