Недостатки предописания класса C++?

require_once и include_once оба требуют, чтобы система сохранила журнал того, что уже включалось/требовалось. Каждый *_once вызов означает проверять тот журнал. Таким образом, существует определенно [приблизительно 1 113] дополнительная работа, сделанная там, но достаточно к вреду скорость целого приложения?

... Я действительно сомневаюсь относительно него... Не, если Вы не находитесь на [1 114] действительно старые аппаратные средства или выполнение его партия .

, Если Вы делающие тысячи из *_once, Вы могли бы сделать работу сами более легким способом. Для простых приложений просто удостоверившись Вы только включали его, как только должен быть достаточными, но если Вы все еще добираетесь, переопределяют ошибки, Вы могли что-то вроде этого:

if (!defined('MyIncludeName')) {
    require('MyIncludeName');
    define('MyIncludeName', 1);
}

я буду лично придерживаться с эти *_once операторы, но на глупом миллионе сравнительного теста передачи, Вы видите различие между двумя:

                php                  hhvm
if defined      0.18587779998779     0.046600103378296
require_once    1.2219581604004      3.2908599376678

10-100Г — медленнее с require_once и любопытно, что require_once по-видимому медленнее в [1 111]. Снова, это только относится к Вашему коду, если Вы работаете *_once тысячи времен.

<час>
<?php // test.php

$LIMIT = 1000000;

$start = microtime(true);

for ($i=0; $i<$LIMIT; $i++)
    if (!defined('include.php')) {
        require('include.php');
        define('include.php', 1);
    }

$mid = microtime(true);

for ($i=0; $i<$LIMIT; $i++)
    require_once('include.php');

$end = microtime(true);

printf("if defined\t%s\nrequire_once\t%s\n", $mid-$start, $end-$mid);
<час>
<?php // include.php

// do nothing.
12
задан Community 23 May 2017 в 12:01
поделиться

2 ответа

Главный недостаток - все. Прямые объявления - это компромисс, позволяющий сэкономить время компиляции и позволить вам иметь циклические зависимости между объектами. Однако цена заключается в том, что вы можете использовать тип только как ссылки и ничего не можете сделать с этими ссылками. Это означает, что нельзя наследовать, передавать его как значение, не использовать вложенный тип или typedef в этом классе и т. Д. Это все большие недостатки.

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

Например:

class A;

struct C 
{
    F(A* a)
    {
        delete a;  // OUCH!
    }
}

Microsoft C ++ 2008 не вызовет деструктор и выдаст следующее предупреждение:

warning C4150: deletion of pointer to incomplete type 'A'; no destructor called
             : see declaration of 'A'

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

22
ответ дан 2 December 2019 в 05:41
поделиться

Из стандарта C ++:

5.3.5 / 5:

«Если удаляемый объект имеет неполный тип класса на момент удаления, и весь класс имеет нетривиальный деструктор или функция освобождения, поведение не определено. "

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

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