Почему это кодирует только печать 42?

2 полезно для кастинга к производному типу.

предположим Животное:

b = a as Badger;
c = a as Cow;

if (b != null)
   b.EatSnails();
else if (c != null)
   c.EatGrass();

станет питаемым минимумом бросков.

6
задан rlazo 18 July 2009 в 19:24
поделиться

7 ответов

Поскольку он демонстрирует неопределенное поведение - вы разыменовываете нулевой указатель.

Когда вы говорите:

 auto_ptr<MyClass> ptr;

, вы создаете автопоинтер, который ни на что не указывает. Это эквивалентно высказыванию:

MyClass * ptr = NULL;

Затем, когда вы говорите:

cout<<ptr->solution()<<endl;

, вы разыменовываете этот нулевой указатель. Это не определено в C ++ - для вашей реализации это работает.

27
ответ дан 8 December 2019 в 02:03
поделиться

std :: auto_ptr не будет автоматически создавать объект для вас. То есть ptr в основном в существующем виде инициализируется значением null. Разыменование этого - неопределенное поведение, и вам просто повезло, и в результате вы получите 42.

Если вы действительно создадите объект:

int main(int argc, char *argv[])
{
    auto_ptr<MyClass> ptr(new MyClass);

    cout << ptr->solution() << endl;

    return 0;
}

Вы получите ожидаемый результат.

21
ответ дан 8 December 2019 в 02:03
поделиться

Потому что вы не знаете вопрос к ответу xD

Кажется, вы не вызываете конструктор, верно?

2
ответ дан 8 December 2019 в 02:03
поделиться

Во-первых, имейте в виду, что оператор -> в auto_ptr по существу пересылается на содержащийся указатель. Итак, для этого обсуждения ваш код в main становится эквивалентным:

MyClass* ptr = NULL;
cout << ptr->solution() << endl;

Затем обратите внимание, что компиляторы, как правило, реализуют функции-члены так, как если бы они не были функциями-членами с этот указатель передан как другой аргумент функции. Итак, с точки зрения вашего текущего компилятора, ваш код в main действует так, как если бы он был:

MyClass* ptr = NULL;
cout << solution(ptr) << endl;

с решением, записанным как:

int solution(MyClass* this) { return 42; }

. В этом случае становится очевидным, почему не было сбоя.


Однако, как уже упоминалось другими, это внутренние детали того, как компиляторы реализуют C ++, которые не определены стандартом языка. Таким образом, теоретически этот код может работать, как описано здесь, на одном компиляторе, но давать сбой или делать что-то еще совсем на другом компиляторе.

Но на практике, даже если стандарт не гарантирует такое поведение, любой конкретный компилятор может гарантируют это, если захотят. Например: поскольку MFC полагается на это поведение, очень маловероятно, что Visual Studio когда-либо перестанет его поддерживать. Конечно, вам придется исследовать каждый конкретный компилятор, в котором можно использовать ваш код, чтобы убедиться, что они действительно гарантируют такое поведение.

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

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

3
ответ дан 8 December 2019 в 02:03
поделиться

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

Когда вы вызываете метод, вы отменяете ссылку на указатель NULL, поэтому, как упомянул Нил, вы теперь находитесь в неопределенном поведении. Но поскольку ваш код не пытается получить доступ к каким-либо переменным-членам, он, к счастью, не дает сбоев.

Попробуйте следующее:

auto_ptr<MyClass> ptr(new MyClass);
2
ответ дан 8 December 2019 в 02:03
поделиться

Потому что ptr не инициализирован, а вы ' повезло. Для этого сначала следует вызвать новый :

auto_ptr<MyClass> ptr( new MyClass );
1
ответ дан 8 December 2019 в 02:03
поделиться

Вы не получаете сбоя, потому что метод «решения» не должен фактически использовать члены класса. Если бы вы возвращали участника или что-то в этом роде, вы, вероятно, получили бы сбой.

1
ответ дан 8 December 2019 в 02:03
поделиться
Другие вопросы по тегам:

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