【问题标题】:Assignment and std::copy of a vector [duplicate]向量的赋值和 std::copy [重复]
【发布时间】:2015-09-15 18:03:22
【问题描述】:

我有大型复杂课程,我想这样做

class A
{
///a lot of things
vector<something> vs;
};

和复制构造函数

A::A(const A& a)
{
   vs=a.vs;
}

反对

A::A(const A& a)
{
   copy(a.vs.begin(),a.vs.end(),back_inserter(vs));
}

哪个更好?

【问题讨论】:

  • @CIsForCookies,不,因为它使用了back_inserter,这使得它没有错......只是不是最佳的。
  • @MegumiBear,如果copy() 版本更好,您不认为库实现者已经更改了赋值运算符来使用它吗?!所以它不能合理地更快或更有效,所以如果你认为长而复杂的表达式比做正确事情的短而简洁的表达式更好,它只会“更好”。但正如下面的答案所示,还有第三种更好的选择。
  • 最好写你的类,这样默认生成的复制构造函数是正确的。如果不能,则将复杂部分包装在正确处理其复制的子类中,直到最终类在没有自定义复制构造函数的情况下工作。

标签: c++ c++11


【解决方案1】:

如果您正在编写自己的复制构造函数,则应使用成员初始化并直接从源构造向量。

A::A(const A& a) : vs(a.vs) {}

现在,如果您的所有类成员都是可复制构造的,那么您不需要复制构造函数,因为编译器提供的就足够了。

【讨论】:

  • 大如果。即使使用std::vector 成员函数,编译器也会为您生成正确的复制构造函数。
  • @TemplateRex 什么是大如果?我只是说“如果”他将创建自己的复制构造函数而不是依赖默认值。
  • 这在新手眼中是个危险的说法,不知不觉中,他们正在编写自己的复制构造函数。
【解决方案2】:

最好的方法是两者都不依赖,让编译器完成它的工作。它会为您生成最佳的复制构造函数,除非您有特殊的数据成员(还有待观察)。然后,只有那时,您才需要担心编写自己的复制构造函数(并且您可以使用@NathanOliver 指出的成员初始化)。

我知道这不是您的实际问题,但与它密切相关:如果您想使用带有向量参数的常规构造函数,最好的方法是使用成员初始化,它将调用 vector 的复制构造函数(和您的标准库将为此编写最佳代码)。

class A
{
public:
    A(vector<something> const& v) : vs(v) {}

    // let the compiler generate the copy constructor, UNLESS you have special data members members        
    A(A const& other): vs(other.vs) { /* e.g. deep copy or other special stuff */ }
private:    
    //a lot of things
    vector<something> vs;
};

【讨论】:

  • 我认为你需要的只是第一段。 OP 没有询问构造函数采用向量参数,所以我认为第二部分只是分散注意力(根据我的经验,你很少想将大向量复制到一个类中,如果你确实想拥有一个向量,那就更好了将其移入)。
  • @ChrisDrew 我知道 OP 并没有询问常规构造函数,但关键是这只是我考虑自己编写东西而不是依赖编译器的地方。已更新,谢谢。移动向量将取决于用例。
  • 既然在 OP 中声明了“很多东西”,那么如果这些其他东西是指针,不要让编译器为你生成它。编译器的默认拷贝构造函数只会做浅拷贝,如果你有指针,你需要定义自己的拷贝构造函数来做深拷贝。
  • @Kirkova 谢谢,已更新,但这应该是例外,而不是大多数课程的常规做法。
  • @TemplateRex 是的,我完全同意你的看法,因为看起来它们可能是新的,我只是想澄清一下。
猜你喜欢
  • 2013-02-05
  • 2016-04-03
  • 2021-08-25
  • 2022-01-14
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多