Я не могу найти какое-либо определение для аннулирование указателей / ссылок в стандарте. Я спрашиваю, потому что я только что узнал, что C ++ 11 запрещает копирование при записи (COW) для строк. Насколько я понимаю, если COW был применен, то p
будет по-прежнему действительным указателем и r
действительная ссылка после следующих команд:
std::string s("abc");
std::string s2(s);
char * p = &(s2[0]);
char & r = s2[0];
s2[1] = "B";
Просто они больше не будут указывать / ссылаться на первый символ s2
, но только для первого персонажа s
,
В стандарте C ++ 11 говорится, что непостоянный std::basic_string::operator[]
не может сделать недействительными указатели / ссылки (а также итераторы) на строковые элементы.
Какие правила говорят, что приведенный выше пример фактически сделает недействительным p
а также r
если COW был реализован?
В стандарте нет определения «недействительности», поскольку этот термин унаследован от английского языка. Это означает, что это означает на английском языке: недействительная ссылка / указатель больше не действительны. Это не может быть использовано.
Однако есть места, где это ограничение явно отмечено. Например, при преобразовании указателя lvalue в rvalue (что происходит во время вычисления выражения):
[conv.lval/2]
В противном случае, если объект, на который ссылается glvalue, содержит недопустимое значение указателя (3.7.4.2, 3.7.4.3), поведение определяется реализацией
Я не могу найти формулировку для ссылок прямо сейчас, но в любом случае очевидно, что вы не можете использовать ссылку на то, что больше не существует.
Например:
std::string * p_s(new ::std::string("abc"));
std::string s2(*p_s); // shares buffer with p_s
char const & ch1(static_cast<::std::string const &>(*p_s)[0]);
char const & ch2(static_cast<::std::string const &>(s2)[0]); // same as ch1
// CoW, ch2 becomes invalid, but is backed by p_s buffer
char & ch(static_cast<::std::string &>(s2)[0]); // backed by new buffer
// both ch1 and ch2 become invalid
delete p_s;