【问题标题】:copy constructor problem while reading an object directly into vector using copy and stream iterators使用复制和流迭代器将对象直接读入向量时的复制构造函数问题
【发布时间】:2010-11-20 08:40:54
【问题描述】:

在运行以下代码时,请一些人解释输出中的行为。 我对复制构造函数被调用的次数有点困惑。

using namespace std;
class A {
    int i;
public:
    A() {
    };
    A(const A& a) {
        i = a.i;
        cout << "copy constructor invoked" << endl;
    };
    A(int num) {
        i = num;
    };
    A& operator = (const A&a) {
        i = a.i;
//      cout << "assignment operator invoked" << endl;
    };
    ~A() {
        cout << "destructor called" << endl;
    };
    friend ostream& operator << (ostream & out, const A& a);
    friend istream& operator >> (istream &in, A&a);
};

ostream & operator << (ostream &out, const A& a) {
    out << a.i;
    return out;
}

istream & operator >> (istream & in, A&a) {
    in >> a.i;
    return in;

}
int main() {
    vector<A> vA;
    copy(istream_iterator<A>(cin), istream_iterator<A>(), back_inserter(vA));
//  copy(vA.begin(), vA.end(), ostream_iterator<A>(cout, "\t"));
    return 0;
}

观察到的输出是

ajay@ubuntu:~/workspace/ostream_iterator/src$ ./a.out 40 copy constructor invoked copy constructor invoked copy constructor invoked copy constructor invoked copy constructor invoked copy constructor invoked copy constructor invoked copy constructor invoked copy constructor invoked copy constructor invoked copy constructor invoked destructor called destructor called destructor called destructor called destructor called destructor called destructor called destructor called destructor called destructor called destructor called destructor called destructor called ajay@ubuntu:~/workspace/ostream_iterator/src$

我认为复制构造函数在插入向量时会被调用一次,因为容器按值存储对象。

【问题讨论】:

  • 你试过开启优化吗?
  • 即使使用 3 级优化,我也得到相同的复制构造调用次数,并且我使用的是 gcc 版本 4.4.3。

标签: c++ stl iterator


【解决方案1】:

istream_iterator 被构建和复制了很多次。这是我的输出:

40
copy constructor invoked
copy constructor invoked
copy constructor invoked
copy constructor invoked
destructor called
destructor called
destructor called
destructor called
copy constructor invoked
copy constructor invoked
destructor called
copy constructor invoked
copy constructor invoked
destructor called
copy constructor invoked
copy constructor invoked
copy constructor invoked
copy constructor invoked
copy constructor invoked
copy constructor invoked
copy constructor invoked

【讨论】:

    【解决方案2】:

    拷贝构造函数至少应该被调用3次:

    • 每个istream_iterator 1 个副本传递给std::copy,如 istream_iterator 存储本地 参数化类型的值和 最有可能在其副本中复制它 构造函数,它们被传递 值std::copy。 (2)
    • 1 通过vA.push_back(...) 插入vector&lt;A&gt; vA,由 back_inserter(vA) 分配 操作员。 (3)

    编译器可能会优化出其中的一些副本,但其他 8 个副本的来源对我来说是个谜。

    编辑:顺便说一下,我收到 8 次调用在 codepad.org 上运行的复制构造函数:http://codepad.org/THFGFCCk

    EDIT2:当我使用 VS2008 运行它时,我收到了 7 次复制构造函数调用。额外的 4 个是围绕输入迭代器复制到 std::copy 以在调试构建中进行边界检查的结果。在完全优化的构建中运行时,我只调用了 3 次复制构造函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-03
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 2011-05-29
      相关资源
      最近更新 更多