Почему это кодирует катастрофический отказ в упомянутых местах?

Ответ - нет.

Неверно

.class {
    background-color: none; /* do not do this */
}

Правильно

.class {
    background-color: transparent;
}

background-color: transparent выполняет то же самое, что вы хотели сделать с background-color: none.

5
задан Shafik Yaghmour 2 April 2015 в 18:52
поделиться

7 ответов

Цитата из этого FAQ: Является ли производный массив таким же, как массив базового?

Производный массив больше, чем Base, арифметика указателя, выполняемая с помощью 2-го объекта baseArray, равна неверно: компилятор использует sizeof (Base) при вычислении адреса для второго объекта, но массив представляет собой массив производных, что означает вычисленный адрес (и последующий вызов функция-член f ()) даже не стоит в начале какого-либо объекта! Это шлепнуть по середине производного объекта.

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

sizeof (Derived) больше, чем sizeof (Base) . Это причина.

Обычно индексация массива объектов Foo по индексу i работает следующим образом:

element_address = array_base_address + i * sizeof(Foo)

Вы можете увидеть, как эта индексация прерывается, если элементы массива не ожидаемого размера. Почему это работает для некоторых индексов, заключается в том, что иногда вычисленный адрес элемента указывает на действительный объект в памяти (но на самом деле это не объект i th).

16
ответ дан 18 December 2019 в 05:12
поделиться

Никогда не обрабатывайте массивы полиморфно. Язык C ++ этого не поддерживает. (См. Также этот Связанный вопрос .)

13
ответ дан 18 December 2019 в 05:12
поделиться

Массивы нельзя использовать для хранения объектов разных типов или для полиморфной обработки объектов - вместо этого сохраните указатели.

Размеры Base и Derived разные - код, который видит массив Base [] , не может определить, что это на самом деле массив Derived [] , а просто индексирует массив, неправильно производя все виды неопределенного поведения .

9
ответ дан 18 December 2019 в 05:12
поделиться

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

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

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

решение состоит в использовании массива указателей. Попробуйте следующее:

void MyWonderfulCode(Base* baseArray)
{
   baseArray[0].SomeFunction();  
   baseArray[1].SomeFunction();  
   baseArray[2].SomeFunction();  
   baseArray[3].SomeFunction();  
   baseArray[4].SomeFunction();  
   baseArray[5].SomeFunction();  
   baseArray[6].SomeFunction();  
   baseArray[7].SomeFunction();  
   baseArray[8].SomeFunction();  
   baseArray[9].SomeFunction();  
}
int _tmain(int argc, TCHAR* argv[])
{
   Base* derivedArray[10];

   for( int i = 0; i < 10; ++i ) derivedArray[i] = new Derived;

   MyWonderfulCode(derivedArray);
   return 0;
}
4
ответ дан 18 December 2019 в 05:12
поделиться

Адриан Григоре ответил:

Если вы используете std :: vector, сбоев быть не должно.

затем удалил ответ из-за комментария:

В этом случае не имеет значения. Произойдет сбой точно так же.

Но Адриан был в основном прав - если MyWonderFulCode принимает вектор или вектор & или вектор * , и вы пытаетесь передать ему vector или vector * , тогда вызывающий код не компилируется. Следовательно, я полагаю, он тоже не вылетает. Невозможно преобразовать из одного векторного типа в другой (по крайней мере, не без создания нового вектора и нарезки в него производных объектов).

Таким образом, в этом случае вам также может понадобиться сбой компиляции, потому что он ' s также невозможно преобразовать из одного типа массива в другой. Проблема в том, что C / C ++ не может отличить указатель от массива при передаче в качестве параметра функции. Из-за совершенно разумного неявного преобразования с Derived * в Base * , мы сталкиваемся с неявным повышающим преобразованием от Derived [] до Base [ ] , который почти всегда не работает. С точки зрения C ++, это совершенно неоправданный reinterpret_cast .

Это одна из причин, по которой программисты на C ++ не используют массивы (если они не должны).

Из-за совершенно разумного неявного преобразования с Derived * в Base * , мы сталкиваемся с неявным повышающим преобразованием от Derived [] до Base [ ] , который почти всегда не работает. С точки зрения C ++, это совершенно неоправданный reinterpret_cast .

Это одна из причин, по которой программисты на C ++ не используют массивы (если они не должны).

Из-за совершенно разумного неявного преобразования с Derived * в Base * , мы сталкиваемся с неявным повышающим преобразованием от Derived [] до Base [ ] , который почти всегда не работает. С точки зрения C ++, это совершенно неоправданный reinterpret_cast .

Это одна из причин, по которой программисты на C ++ не используют массивы (если они не должны).

2
ответ дан 18 December 2019 в 05:12
поделиться
Другие вопросы по тегам:

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