В классах C ++ есть функция ввода их имени в свою область действия ( [класс] / 2 ):
Имя класса также вставляется в объем самого класса; это известно как имя введенного класса . Для проверки доступа имя введенного класса рассматривается так, как если бы это было публичное имя участника.
. В приведенном фрагменте кода используется Это. В определенных контекстах
Commitment::Commitment
называет сам класс, а в других - c'tor. Только последнийCommitment(
, где вы открываете круглые скобки, начинается определение c'tor.И это может выглядеть намного хуже:
struct foo { foo(); }; foo::foo::foo::foo() = default;
Который вы можете видеть действительный C ++ Live .
Во-первых, очень интересный вопрос.
Я бы сказал, что это неопределенное поведение, предполагая, что «оборванная ссылка» означает, что «время жизни объекта« ссылка на объект »закончилось, и хранилище, которое занимал объект , имеет были повторно использованы или выпущены ». Я основываю свои рассуждения на следующих стандартных правилах:
3.8 §3:
Свойства, приписываемые объектам в рамках этого международного стандарта, применяются к данному объекту только в течение его жизни. [Примечание: В частности, до начала жизни объекта и после его окончания жизни существуют существенные ограничения на использование объекта, как описано ниже ...]
blockquote>Все случаи «как описано ниже» относятся к
До того, как срок жизни объекта запустился, но после того, как хранилище, которое будет занимать объект, было выделено38, или после того, как срок жизни объекта закончился и до хранилище, которое занимаемый объект повторно используется или освобожден
blockquote>1.3.24: неопределенное поведение
поведение, для которого настоящий международный стандарт не предъявляет требований [Примечание: неопределенное поведение можно ожидать, если в этом Международном стандарте отсутствует явное определение поведения или когда программа использует ошибочную конструкцию или ошибочные данные. ...]
blockquote>Я применяю следующий цикл мыслей к приведенным выше цитатам:
- Если стандарт не описывает поведение для ситуации, Функция не указана.
- Стандарт описывает только поведение объектов в течение их жизни и несколько особых случаев вблизи начала и конца их жизни.
- Таким образом, использование ссылки danling каким-либо образом не имеет поведения, предписанного стандартом, поэтому поведение не определено.
Что делает неправильное поведение недопустимого объекта (ссылка, указатель, что угодно) неопределенным: lvalue-to-rvalue conversion (§4.1):
Если объект, к которому относится ссылка glvalue не является объектом типа T и не является объектом типа, производного от T, или если объект не инициализирован, программа, которая требует этого преобразования, имеет неопределенное поведение.
blockquote>Предполагая, что мы 't перегружен
operator&
, унарный оператор&
принимает lvalue в качестве своего операнда, поэтому никакого преобразования не происходит. Наличие только идентификатора, как и вx;
, также не требует преобразования. Вы получите только неопределенное поведение, когда ссылка используется как операнд в выражении, ожидающем, что этот операнд будет значением rvalue, что имеет место для большинства операторов. Дело в том, что выполнение&x
фактически не требует доступа к значениюx
.Я считаю, что ваш код хорошо определен.
Когда перегрузка
operator&
была перегружена, выражение&x
преобразуется в вызов функции и не подчиняется правилам встроенных операторов - вместо этого он следует правилам вызова функции. Для функции&x
вызов функции перевода означает либоx.operator&()
, либоoperator&(x)
. В первом случае преобразование lvalue-rvalue будет происходить наx
, когда используется оператор доступа к члену класса. Во втором случае аргументoperator&
будет инициализирован с помощьюx
(как вT arg = x
), а поведение этого зависит от типа аргумента. Например, в случае, если аргумент является ссылкой lvalue, нет неопределенного поведения, поскольку преобразование lvalue-rvalue не происходит.Итак, если
operator&
перегружен для типаx
, код может быть или не быть корректным, в зависимости от вызова функцииoperator&
.Можно утверждать, что унарный оператор
&
полагается на наличие хотя бы некоторой допустимой области что у вас есть адрес:В противном случае, если тип выражения равен
blockquote>T
, результат имеет тип «указатель наT
» и является значением praleue, которое является адрес выделенного объектаИ объект определяется как область хранения. После уничтожения объекта, эта область хранения больше не существует.
Я предпочитаю полагать, что это приведет только к неопределенному поведению, если к нему действительно обращается недопустимый объект. Ссылка все еще полагает, что это относится к некоторому объекту, и он может с радостью указать адрес, даже если он не существует. Однако это, кажется, некорректная часть стандарта.
Кроме
В качестве примера неопределенного поведения рассмотрим
x + x
. Теперь мы попали в другую нечеткую часть стандарта. Категория значений операндов+
не указана. Как правило, из § 5/8 вытекает, что если он не указан, тогда он ожидает значение prvalue:Всякий раз, когда выражение glvalue появляется как операнд оператора, который ожидает prvalue для этого операнда , для преобразования выражения в prvalue применяются переменные lvalue-to-rvalue (4.1), стандартные переменные (4.2) или стандартные функции (4.3).
blockquote>Теперь, поскольку
x
является lvalue, требуется преобразование lvalue-rvalue, и мы получаем неопределенное поведение. Это имеет смысл, потому что добавление требует доступа к значениюx
, чтобы он мог выработать результат.
Предположим, что x
был инициализирован действительным объектом, который был затем уничтожен, применяется §3.8 / 6:
Аналогично, до того, как срок жизни объекта начался, но после хранения который будет занимать объект, был выделен или, по истечении срока жизни объекта и до хранения, которое объект занят повторно используется или выпущен, может использоваться любое значение gl, которое ссылается на исходный объект, но только ограниченным образом. По строительству или разрушению объекта см. 12.7. В противном случае такое значение glvalue относится к выделенному хранилищу (3.7.4.2), и использование свойств glvalue, которые не зависят от его значения, четко определено. Программа имеет неопределенное поведение, если:
- преобразование lvalue-to-rvalue (4.1) применяется к такому glvalue,
- glvalue используется для доступа к нестатическому член данных или вызов нестатической функции-члена объекта или
- glvalue привязан к ссылке на виртуальный базовый класс (8.5.3) или
- glvalue используется как операнд dynamic_cast (5.2.7) или как операнд typeid.
blockquote>Итак, просто принимая адрес хорошо определен и (ссылаясь на соседний абзацы) даже можно продуктивно использовать для создания нового объекта вместо старого.
Что касается not , берущего адрес и просто записывающего
x
, это действительно делает абсолютно ничего, и это правильное подвыражение&x
. Так что это тоже нормально.