容器中的对象拷贝

《Effective STL》第3条

当往容器中保存对象时,保存的并不是提供给容器的那些对象,而是那些对象的拷贝。

如何拷贝?利用的是对象的拷贝构造函数。

 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4 
 5 class Foo
 6 {
 7 public:
 8     Foo(int x):_x(x)
9 { 10 cout << "constructor" << endl; 11 } 12 ~Foo() 13 { 14 cout << "destructor" << endl; 15 } 16 17 private: 18 int _x; 19 }; 20 21 int main() 22 { 23 vector<Foo> vec; 24 Foo f(1); 25 vec.push_back(f); 26 return 0; 27 }

成功执行,输出

constructor
destructor
destructor

编译会帮忙生成拷贝构造函数

如果禁用拷贝构造函数

#include <iostream>
#include <vector>
using namespace std;

class Foo
{
public:
    Foo(int x):_x(x)
    {
        cout << "constructor" << endl;
    }
    ~Foo()
    {
        cout << "destructor" << endl;
    }

    Foo (const Foo&) = delete;
private:
    int _x;
};

int main()
{
    vector<Foo> vec;
    Foo f(1);
    vec.push_back(f);
    return 0;
}

编译时会报错

/usr/include/c++/4.7/bits/stl_construct.h:77:7: error: use of deleted function ?.oo::Foo(const Foo&)?

 

 如果自己定义了拷贝构造函数

#include <iostream>
#include <vector>
using namespace std;

class Foo
{
public:
    Foo(int x):_x(x)
    {
        cout << "constructor" << endl;
    }
    ~Foo()
    {
        cout << "destructor" << endl;
    }

    Foo (const Foo& f)
    {
        cout << "copy constructor" << endl;
        _x = f._x;
    }
private:
    int _x;
};

int main()
{
    vector<Foo> vec;
    Foo f(1);
    vec.push_back(f);
    return 0;
}

执行输出:

constructor
copy constructor
destructor
destructor

执行了自己定义的拷贝构造函数

对于内置类型来说,总是简单的按位拷贝。

 

结论:由于容器会创建拷贝,所以如果一个对象的拷贝很费时,那就有可能成为性能瓶颈。

 

如何提高性能?

避免拷贝

 

使用指针

 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4 
 5 class Foo
 6 {
 7 public:
 8     Foo(int x):_x(x)
 9     {
10         cout << "constructor" << endl;
11     }
12     ~Foo()
13     {
14         cout << "destructor" << endl;
15     }
16 
17     Foo (const Foo& f)
18     {
19         cout << "copy constructor" << endl;
20         _x = f._x;
21     }
22 private:
23     int _x;
24 };
25 
26 int main()
27 {
28     vector<Foo*> vec;
29     Foo* f = new Foo(1);
30     vec.push_back(f);
31     return 0;
32 }

输出

constructor

这里有个问题,new 的指针没有释放,容器对象在析构时,不能自动释放成员指针指向的内存。

 必须自己释放

1 int main()
2 {
3     vector<Foo*> vec;
4     Foo* f = new Foo(1);
5     vec.push_back(f);
6     delete f;
7     return 0;
8 }


有点麻烦,现在可以考虑使用智能指针了

 1 #include <iostream>
 2 #include <memory>
 3 #include <vector>
 4 using namespace std;
 5 
 6 class Foo
 7 {
 8 public:
 9     Foo(int x):_x(x)
10     {
11         cout << "constructor" << endl;
12     }
13     ~Foo()
14     {
15         cout << "destructor" << endl;
16     }
17 
18     Foo (const Foo& f)
19     {
20         cout << "copy constructor" << endl;
21         _x = f._x;
22     }
23 private:
24     int _x;
25 };
26 
27 int main()
28 {
29     vector<shared_ptr<Foo>> vec;
30     shared_ptr<Foo> f = make_shared<Foo>(1);
31     vec.push_back(f);
32     return 0;
33 }

执行输出

constructor
destructor

只构造了一次对象,并且可以正常释放了。

 

posted @ 2016-04-23 14:36  Kjing  阅读(429)  评论(0编辑  收藏  举报