Что представляет собой адрес вектора? - PullRequest
4 голосов
/ 02 ноября 2019

Если я верну вектор из функции, объект, которому он назначен, будет иметь тот же адрес (без возврата в качестве ссылки), что и объект, объявленный в функции. Например:

vector<int> f() {
    vector<int> foo(5);
    cout << &foo << endl;

    return foo;
}

int main() {

    vector<int> bar = f();
    cout << &bar << endl; // == &foo

    return 0;
}

Тогда я предположил, что это происходит из-за конструктора копирования, и оператор & может быть перегружен таким образом, что он печатает адрес определенного члена векторного класса, который былскопировал из фу в бар. Но если я изменю сценарий и переместлю f () внутри класса, поведение будет таким, как я изначально ожидал: & foo! = & Bar:

class A {
    vector<int> foo;
public:
    vector<int> f() {
        foo.push_back(10);
        cout << &foo << endl;

        return foo;
    }
};

int main() {
    A a;
    vector<int> bar = a.f();
    cout << &bar << endl; // != &foo

    return 0;
}

Можете ли вы объяснить, что происходит?

1 Ответ

2 голосов
/ 02 ноября 2019

Что представляет собой адрес вектора?

Память компьютера может быть из массива байтов. Адрес памяти является указателем на этот образный массив. Это то же самое для всех объектов, включая векторы.

Если я верну вектор из функции, объект, которому он назначен, будет иметь такой же адрес (без возврата в качестве ссылки), кактот, который объявлен в функции.

Стандарт не гарантирует этого. Но это действительно возможно. Это происходит всякий раз, когда оптимизация именованных возвращаемых значений используется для исключения копирования / перемещения возвращаемого значения.

Тогда я предположил, что это происходит из-за того, что оператор ... & может быть перегружен втаким образом, что ...

Адрес оператора вектора не перегружен.

Можете ли вы объяснить, что происходит?

Вы вернетеськопия члена, а не локальная автоматическая переменная. NRVO не может использоваться в этом случае.

Независимо от подобъектов, более одного объекта не могут перекрывать одну и ту же память в любой момент времени. Если два объекта существуют одновременно, то каждый из них должен иметь отдельный адрес. С другой стороны, когда память одного объекта освобождается, она может быть повторно использована другим объектом.

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

Во втором примере время жизни a и, следовательно, его член перекрываются со временем жизни bar, и поэтому они не могутПерекрытие в памяти.

...