向量如何按值传递?

How Do Vectors Pass By Value?

提问人:Osama Alkurdi 提问时间:8/26/2022 最后编辑:Osama Alkurdi 更新时间:8/26/2022 访问量:292

问:

如果我创建了一个矢量对象,则将分配一个大小为 24 字节(在我的机器上)的实例。 我读到一个向量对象包含(粗略地说)两个元素:

  1. 指针指向堆内存中存储的数据的第一个元素。
  2. 数据的大小。

我知道按值传递不会影响原始数据,假设我们已经(按值)将一个字符向量传递给一个函数,并且上面的两个元素将被复制(指针和大小),因此复制的指针(在复制的向量对象中)仍然会指向原始指针(在原始向量对象中)指向的相同数据

我的问题是,如果复制的指针仍然指向相同的数据(如果我错了,请纠正我),为什么更改复制的向量数据不会影响原始向量(两个向量都被复制了,其中的指针也被复制了)?

说明我的想法

#include <iostream>
#include <vector>

using namespace std;

void printVector(vector<char> vec) {
    for (char c: vec) 
        cout << c << " ";
    cout << endl;
}

void changeVector(vector<char> copiedVector) {
    copiedVector.at(0) = 'x';
    copiedVector.at(1) = 'y';
    copiedVector.at(2) = 'z';
    
    printVector(copiedVector);
}

int main() {
    vector<char> originalVector {'a', 'b', 'c'};
    
    cout << "The original vector contains: ";
    printVector(originalVector);
    cout << endl;
    
    cout << "The copied vector contains: ";
    changeVector(originalVector);
    cout << endl;
    
    cout << "The original vector (after calling changeVector function) contains: ";
    printVector(originalVector);
    cout << endl;

    return 0;
}

输出:

原始向量包含:a b c

复制的向量包含:x y z

原始向量(调用 changeVector 函数后)包含: 乙 C

很抱歉发布了愚蠢的问题,我试图做很多搜索,但我没有得到我想要的答案。

我是C++的新手,所以请温柔一点,以简单详细的方式向我解释这一点,以便我纠正自己。

提前致谢。

C++ 矢量 按值传递

评论

1赞 πάντα ῥεῖ 8/26/2022
value 参数包含您原件的深层副本,您能详细说明一下您的担忧吗?
5赞 Richard Critten 8/26/2022
复制 a 会对向量及其拥有的元素进行深度复制。std::vector
2赞 Sam Varshavchik 8/26/2022
这是不正确的。当 被复制时,基础数据也会被复制。std::vector
1赞 user4581301 8/26/2022
每个公司都拥有自己的数据,并实施五法则来维护和转让所有权。std::vector
1赞 Karl Knechtel 8/26/2022
这回答了你的问题吗?什么是 C++ 中的复制构造函数?

答:

2赞 user17732522 8/26/2022 #1

当我们说一个对象是在 C++ 中复制时,我们并不是说简单地复制了该对象占用的存储字节,就好像您正在描述的那样。memcpy

相反复制意味着调用类类型的复制构造函数(或复制赋值运算符)以对类型有意义的方式执行复制操作。的复制构造函数执行深度复制,分配新内存以存储原始向量的每个元素的副本,并且新向量的内部指针将设置为指向此新分配的内存。std::vector

在调用中,参数是 type 的左值,函数的参数是 (non-reference) 。调用函数时,将从参数复制初始化参数。因为是一个类类型,这意味着编译器将查找一个(非)构造函数,该构造函数只接受一个非-类型的左值参数。复制构造函数具有changeVector(originalVector);std::vector<char>std::vector<char>std::vector<char>explicitstd::vector<char>conststd::vector<char>

vector(const vector&)

因此,这是一个有效的选择,并且将被选中来构造 in 参数。std::vector<char>

(编译器还将考虑参数类型中的转换函数来初始化参数,但这与此处无关。