【问题标题】:Copy constructor get called more than one time复制构造函数被多次调用
【发布时间】:2019-10-24 13:46:12
【问题描述】:

以下代码输出:

Default ctor is called
Copy ctor is called
Default ctor is called
Copy ctor is called
Copy ctor is called

为什么对于每个push_back(),复制构造函数的调用都加1? 我认为它应该只调用一次。 有什么我想念的吗?我需要详细的解释。

class A
{
public:
    A()
    {
        std::cout << "Default ctor is called" << std::endl;
    }
    A(const A& other)
    {
        if(this != &other)
        {
            std::cout << "Copy ctor is called" << std::endl;
            size_ = other.size_;
            delete []p;
            p = new int[5];
            std::copy(other.p, (other.p)+size_, p);
        }
    }
    int size_;
    int* p;
};
int main()
{
    std::vector<A> vec;
    A a;
    a.size_ = 5;
    a.p = new int[5] {1,2,3,4,5};
    vec.push_back(a);

    A b;
    b.size_ = 5;
    b.p = new int[5] {1,2,3,4,5};
    vec.push_back(b);

    return 0;
}

【问题讨论】:

  • 要将class A 推送到向量上,它需要创建A 的副本。如果不希望这样做,您可以使用智能指针或简单地指向新对象。
  • @RichardNixon 是的,我知道。我的问题是为什么复制构造函数被调用不止一次而不是一次。
  • 啊,是的,对不起。做一些实验表明 push_back() 似乎创建了列表中所有已经的副本(尝试添加c)。恐怕这取决于 vector() 的内部结构。

标签: copy-constructor push-back


【解决方案1】:

这是因为您的示例中的 push_back 每次都必须进行重新分配。如果您提前reserve 大小,那么您只会看到一份。

std::vector<A> vec;
vec.reserve(10);

【讨论】:

  • 是的,你是对的,但这是一种奇怪的行为。你知道为什么push_back 会这样吗?无法使用realloc 实现,例如如果堆中有空间则使用已存在的内存?
  • A vector 可以以连续的方式访问,因此您可以执行 vec[n],而 std::list 则无法执行此操作。我不知道 vector 的内部工作原理,但我想这是在其内部空间耗尽时添加新条目的最安全方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-05
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 1970-01-01
相关资源
最近更新 更多