Глобальная строка const и плохо пахнет мне, действительно ли она безопасна?

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

const string& SomeConstant = "This is some constant text";

Лично мне это плохо пахнет, потому что ссылка ссылается на то, что я предполагаю, является анонимным объектом, построенным из данного массива char.

Синтаксически, он легален (по крайней мере, в VС++ 7), и, похоже, он работает, но на самом деле я бы предпочел, чтобы он удалил его, и поэтому нет никакой двусмысленности в отношении того, что он делает.

Итак, разве это ИСТИННО безопасно и законно, и я одержим? Строит ли построенный объект temp гарантированный срок службы? Я всегда предполагал, что анонимные объекты, используемые таким образом, были уничтожены после использования...


Итак, мой вопрос также может быть обобщен на время анонимного объекта. Является ли стандарт диктовать время жизни анонимного объекта? Будет ли он иметь такое же время жизни, как и любой другой объект в той же области? Или это дается только время жизни выражения?


Также, делая это как локальный, он, очевидно, имеет разные значения:

class A
{
    string _str;

public:
    A(const string& str) :
        _str(str)
    {
        cout << "Constructing A(" << _str << ")" << endl;
    }

    ~A()
    {
        cout << "Destructing A(" << _str << ")" << endl;
    }
};

void TestFun()
{
    A("Outer");
    cout << "Hi" << endl;
}

Показывает:

Построение A (Outer); Уничтожение A (Outer); Привет

Ответ 1

Это совершенно законно. Он не будет разрушен до завершения программы.

EDIT: Да, это гарантировано:

"Все объекты, не имеющие динамических время хранения, не имеют потока времени хранения и не являются локальными имеют статическую продолжительность хранения. хранение этих объектов должно продолжаться на протяжении всей программы (3.6.2, 3.6.3).

- 2008 Рабочий проект, стандарт для языка программирования С++, § 3.7.1 с. 63

Как отметил Мартин, это не весь ответ. Стандартный проект дополнительных примечаний (§ 12.2, стр. 250-1):

"Создаются временные классы типа класса в разных контекстах: привязка значения rvalue к ссылке (8.5.3) [...] Даже когда создание временного объекта (12.8), все семантические ограничения должны соблюдаться, как если бы временный объект был создан. [...] Временные объекты уничтожены как последний шаг в оценке полное выражение (1.9), которое (лексически) содержит точку, в которой они были создано. [...] Есть два контекста в котором временные чем точка конца полное выражение. [...] Второй контекст - это когда ссылка привязана к временному. Временное ссылка привязана или временный, являющийся полным объектом подобъекта, к которому ссылка связана с сохранением времени жизни ссылка, кроме как указано ниже".

Я тестировал в g++, если это заставляет вас чувствовать себя лучше.;)

Ответ 2

Да, он действителен и легален.

const string& SomeConstant = "This is some constant text";

// Is equivalent too:

const string& SomeConstant = std::string("This is some constant text");

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

Это гарантируется стандартом.

Примечание:

Хотя это законно. Я бы не использовал его. Простейшим решением было бы преобразовать его в const std::string.

Использование:

В этой ситуации, поскольку переменная находится в глобальной области действия, она действительна для всей длины программы. Таким образом, его можно использовать, как только выполнение входит в main() и не должно быть доступно после того, как исполнитель выйдет из main().

Хотя это технически может быть avilable до того, как ваше использование этого в конструкторах/деструкторах глобальных объектов должно быть смягчено с известной проблемой порядка инициализации глобальной переменной.

Дополнительные мысли:

Это, с другой стороны, не пострадает от проблемы:

char const* SomeConstant = "This is some constant text";

И может использоваться в любой точке. Просто мысль.

Ответ 3

Это может быть законным, но все же уродливым. Оставьте ссылку!

const string SomeConstant = "This is some constant text";

Ответ 4

Это так же законно, как и уродливо.

Ответ 5

Право на продление временной переменной с помощью ссылки const, это используется Alexandrescu ScopeGaurd, см. это превосходное объяснение Herb Sutter называемый Кандидат на "Самый важный const" .

При этом этот конкретный случай является злоупотреблением этой функцией С++, и ссылка должна быть удалена, оставив простой const string.

Ответ 6

Объявляя его как const (что означает, что он не может быть изменен), а затем делает его ссылкой, что означает, что кто-то может его изменить, по крайней мере кажется плохим. Кроме того, как я уверен, вы понимаете, глобальные переменные BAD и редко необходимы.

Ответ 7

Хорошо, меня исправит, если я уйду с глубокого конца, но здесь мои выводы прислушиваются ко всем твоим прекрасным ответам:

A) он синтаксически и логически легален и продлевает время жизни временного/анонимного от уровня выражения до уровня ссылки. Я проверил это в VС++ 7 с помощью:

class A { 
    public: A() { cout << "constructing A" << endl; }
    public: ~A() { cout << "destructing A" << endl; }
};

void Foo()
{
    A();
    cout << "Foo" << endl;
}

void Bar()
{
    const A& someA = A();
    cout << "Bar" << endl;
}

int main()
{
    Foo();    // outputs constructing A, destructing A, Foo
    Bar();    // outputs constructing A, Bar, destructing A
    return 0;
}

B) Хотя это является законным, это может привести к некоторой путанице в отношении фактического времени жизни, и ссылка в этих случаях не дает вам никакой пользы объявить ее как ссылку без ссылки, поэтому следует, вероятно, избегать ссылки и даже быть дополнительным пространством. Поскольку нет никакой пользы для него, это ненужное обфускация.

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

Звучит правильно?