Почему C ++ не использует .
, где он использует ::
, потому что именно так определяется язык. Одна из правдоподобных причин - ссылаться на глобальное пространство имен, используя синтаксис ::a
, как показано ниже:
int a = 10;
namespace M
{
int a = 20;
namespace N
{
int a = 30;
void f()
{
int x = a; //a refers to the name inside N, same as M::N::a
int y = M::a; //M::a refers to the name inside M
int z = ::a; //::a refers to the name in the global namespace
std::cout<< x <<","<< y <<","<< z <
Не знаю, как Java решает это. Я даже не знаю, есть ли в Java глобальное пространство имен. В C # вы ссылаетесь на глобальное имя, используя синтаксис global::a
, что означает, что даже C # имеет оператор ::
.
, но я не могу представить ни одной ситуации, в которой синтаксис
Кто сказал, что синтаксис, подобный
a.b::c
, не является законным?Рассмотрим эти классы:
struct A { void f() { std::cout << "A::f()" << std::endl; } }; struct B : A { void f(int) { std::cout << "B::f(int)" << std::endl; } };
Теперь см. Это ( ideone ):
B b; b.f(10); //ok b.f(); //error - as the function is hidden
b.f()
не может быть вызвано так, как функция скрыта, а GCC дает это сообщение об ошибке:error: no matching function for call to ‘B::f()’
Для вызова
b.f()
(или, скорее,A::f()
) вам нужен оператор разрешения области видимости:b.A::f(); //ok - explicitly selecting the hidden function using scope resolution
На самом деле это не проблема; так работают массивы (и другие объекты) в Python.
Подумайте об этом так: массив, который вы создали в своем примере кода, - это объект, который находится в некотором месте в памяти. Но вы не можете использовать его в своей программе, указав Python, где его искать; вы должны дать ему имя. Когда вы пишете
a = np.array([[1,2],[3,4]])
, вы одновременно создаете массив и создаете имя a
, которое ссылается на него. С этого момента Python знает, что a
относится к «адресу памяти 0x123674283» (или какому-то другому). В среде выполнения Python есть внутренняя таблица (называемая «таблицей символов», если я правильно помню), которая содержит всю эту информацию, поэтому после выполнения указанной выше строки кода Python эта таблица будет содержать
...,
'a' : 0x123674283,
...
. переменную в другую, например
b = a
Python не копирует весь массив, потому что, если бы это был большой массив, это заняло бы много времени. Вместо этого он переходит в таблицу символов и копирует адрес памяти для a
в новую строку в таблице для b
. Итак, вы получаете
...,
'a' : 0x123674283,
...,
'b' : 0x123674283,
...
Итак, вы видите, a
и b
на самом деле относятся к одному и тому же месту в памяти, то есть к одному и тому же объекту. Любые изменения, внесенные вами в один, будут отражены в другом, поскольку это всего лишь два названия одного и того же объекта.
Если вы действительно хотите сделать копию массива, вы должны вызвать метод, чтобы сделать это явно.Массивы Numpy имеют метод copy
, который вы можете использовать только для этой цели. Итак, если вы напишете
b = a.copy()
, тогда Python сначала фактически сделает копию массива, то есть выделит новую область памяти, скажем, по адресу 0x123904381, затем перейдет к адресу памяти 0x123674283 и скопирует все значения массив из последнего раздела памяти в первый. Таким образом, один и тот же контент находится в двух разных местах памяти.
...,
'a' : 0x123674283,
...,
'b' : 0x123904381,
...
Теперь, когда вы меняете один из элементов b
, это изменение не будет отображаться в a
, поскольку a
и b
больше не относятся к одному и тому же разделу памяти компьютера. Поскольку существует две независимые копии данных массива, вы можете изменить одну, не затрагивая другую.