Сфера двусмысленности во вложенных - PullRequest
2 голосов
/ 16 февраля 2012

Допустим, у каждого есть класс Foo, такой как

class Foo {
public:
  void bar();
  operator bool() const { return true; }
};

тогда можно сделать

if(Foo foo = Foo())
{
  if(Foo foo = Foo())
  {
    foo.bar();
  }
}

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

Я ожидаю, что foo.bar () будет выполняться на втором foo (его область действия "ближе"), но я гарантирую, что это на самом деле объект, отличный от первого foo? Кроме того, каждый из них независимо расположен (их деструктор называется) в конце соответствующих блоков if?

Ответы [ 3 ]

7 голосов
/ 16 февраля 2012

C ++ вполне рад объявить переменную с тем же именем, если она находится во вложенной области видимости, поэтому двусмысленности нет.

Я ожидаю, что foo.bar () будет выполняться на втором foo (его область "ближе")

Вы правы

но я гарантирую, что это на самом деле объект, отличный от первого foo?

Да

Кроме того, каждый из них независимо расположен (их деструктор называется) в конце соответствующих блоков if?

Да

4 голосов
/ 16 февраля 2012

Я ожидаю, что foo.bar () будет выполняться на втором foo (его область "ближе")

Correct.

но я гарантирую, что это на самом деле объект, отличный от первого foo?

Да.

Кроме того, каждый из них независимо расположен (их деструктор называется) в конце соответствующих блоков if?

Да, у вас есть.

2 голосов
/ 16 февраля 2012

Использование операторов if и инициализации объекта класса в вашем примере имеет тенденцию затенять релевантный момент: объявления во внутренних областях являются абсолютно допустимыми и скрывают объявления с одинаковыми именами во внешних областях.

Aвозможно, более ясный пример:

#include <iostream>
int main() {
    const int x = 10;
    std::cout << "outer x is " << x << "\n";
    {
        const double x = 12.34;
        std::cout << "    inner x is " << x << " (it hides the outer x)\n";
    }
    std::cout << "outer x is still " << x << " (inner x no longer exists)\n";
}

Вывод:

outer x is 10
    inner x is 12.34 (it hides the outer x)
outer x is still 10 (inner x no longer exists)

Обратите внимание, что внутренние и внешние x s даже не относятся к одному и тому же типу.

Хотя это законно, обычно это не очень хорошая идея;у компилятора с этим нет проблем, но это может сбить людей с толку.Если вы скомпилируете с g++ -Wshadow, вы получите предупреждение:

c.cpp: In function ‘int main()’:
c.cpp:6:22: warning: declaration of ‘x’ shadows a previous local
c.cpp:3:15: warning: shadowed declaration is here
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...