【问题标题】:How does C++ cope with vector of objects with the same name?C++ 如何处理同名对象的向量?
【发布时间】:2018-08-22 08:44:15
【问题描述】:

假设我在某个本地范围内创建了一个对象,并将其添加到存在于该范围之外的向量中。

std::vector<sometype> Vec;
for( int i = 0, etc... )
{
    sometype Object;
    Vec.push_back(Object);
}

现在 Object 的副本将被传递给 Vec,而 Object 本身将被销毁。

但是,如果我继续这样做,我将继续创建许多名为“Object”的对象,这些对象存储在我的向量中。现在我可以通过它们的索引来访问它们,但是 C++ 如何处理我有很多对象显然都同名的事实呢?

【问题讨论】:

  • 名称是本地变量。该变量在每次迭代时创建和销毁,每次引用不同的对象(通常恰好位于内存中的同一地址,但这只是编译器实现的细节)。对象的生命周期与其作用域 相关联——例如,在函数顶部声明的变量也是如此:每次调用函数时,都会为其作用域内的变量创建新对象。
  • 对象在循环中不断被创建和销毁。循环内只有一个。它的名字无所谓,那纯粹是为了程序员的利益。
  • 在 OO 语言中,有时将对象分类为“值对象”、“实体对象”和“服务对象”是很方便的。如果 sometype 是一个值类型,那么一切都应该是好的。如果 sometype 是实体类型(即对象具有标识),那么这可能是一个问题——可能由std::vector&lt;std::shared_ptr&lt;sometype&gt;&gt;(或std::unique_ptr)解决。服务对象通常是单例或单态或(面向公众的)无状态的。
  • @Eljay 这与问题有什么关系?
  • @PasserBy • 如果对象是实体对象,那么对向量执行 push_back 将失去标识。如果这很重要。很难说,以非 MVCE 为例。

标签: c++ vector


【解决方案1】:

sometype 对象的名称无关紧要。您是正确的,每次调用 push_back 时,Object 的副本将被放置到 Vec 上,但它不是放置在向量上的对象的名称。一个实际的对象被放置到向量中,可以通过适当地索引到向量中来引用它。

【讨论】:

    【解决方案2】:

    对象的名称不是Object。那是变量的名称。用于复制构造向量元素的变量名称与该元素没有任何关系。

    对象通常没有名称。有些确实如此,特别是那些由变量命名的对象。但是动态构造的对象没有。甚至一个对象的变量和名称之间的联系也是相当松散的。例如,如果您只有一个指向对象的指针,则无法确定该对象是否由变量命名。

    【讨论】:

      【解决方案3】:

      只需考虑一个变量名作为一些内存地址的替代表示(对你来说是透明的!)。您已经在内存中的某个特定位置创建了一个对象,该对象由您的变量名引用。您现在将对象复制到一个新位置,该位置具有不同的地址,与您的原始对象所在的地址完全无关,因此它也会获得一个新的“名称”,而变量名称仍然引用旧地址(只要仍在范围内)。

      当然,在向量内部,这个新的“名称”不仅仅是一个地址,而是一个如何找到它的秘诀(vec[someIndex]:“转到向量内部数据的开头,你会在给定的位置找到你的对象从那里偏移”,也就是;粗俗地说,索引运算符实际上做了什么——对你来说又是透明的)。

      【讨论】:

        【解决方案4】:

        C++ 如何处理同名对象的向量。

        不合逻辑。

        在您的 for 循环中,“对象”一词出现了 2 次。

        a) 第一次出现“sometype Object;”是“自动”内存区域的声明和初始化。在这种情况下,“对象”一词在有限的范围和生命周期内标识实例的位置。

        b) 第二次出现“Vec.push_back(Object);”是编译器生成代码以将实例传递给函数“push_back”的命令。在这里,它是通过引用(而不是值)传递的,这意味着函数“接收的地址”,而不是实际的实例。

        区别是这样的:

        • 函数的形参是“const T& value”

        (基于 cppreference.com,其中函数声明为 std::vector::push_back(const T& value),正式名称为“value”。)

        • 该函数的实际参数是“sometype& Object”。

        (来自您的代码)

        • 显然,这两个名称并不相同。

        因此,您的问题得出“一个结论或陈述在逻辑上与先前的论点或陈述不相符。”


        总结:

        a) 您的代码没有所谓的“价值”或“T”。

        b) 如果您检查 std::vector 代码,您将找不到“sometype”或“Object”。

        名字不一样。

        【讨论】:

        • 如果您在 gdb 中反汇编 /m,您可能会惊讶地发现“Object”被拼写了多少次……在 c++ 代码中被拼写了两次,但在汇编中却没有!符号名称仅在编译时使用。
        猜你喜欢
        • 2021-09-04
        • 1970-01-01
        • 2016-02-29
        • 2013-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多