C++三大函数(The Big Three)

本文用Markdown编辑,这里对Markdown的支持不完善,更好的阅读体验请移步:我的Markdown文本

C++三大函数:

  • 析构函数
  • 复制构造函数
  • operator=

析构函数

函数模样:~S()

当一个对象超出作用域或执行delete的时候,析构函数就被调用。

复制构造函数

函数模样:S(const S& s)

以下情况,复制构造函数均会被调用:

  • 声明的同时初始化:

    S s1 = s2;  //注意此时虽然出现=,但是不是调用operator=哦
    S s1(s2);
    
  • 调用函数时使用按值传递(而不是按引用传递)

    void f(S s);
    S s1;
    f(s1);
    
  • 通过值返回对象

    S f()
    {
        S s1;
        return s1;
    }
    

operator=

函数模样:const S& operator=(const S& s)

当=应用于两个已经构造的对象时,就调用复制赋值运算符operator=。

S s1;
s1 = s2;    //注意与S s1 = s2; 的区别

注意事项:

  1. 三大函数不手动实现的时候,会使用默认的版本。比如operator=的默认版本会依次为数据成员复制,如果是基本数据类型自然没什么问题,但当数据成员含有指针的时候,operator的只会进行浅复制,即只是指针本身被复制,而不是指针所指向的内容被复制。见下例。

    class S
    {
        public:
        int *p;
        S(int x=0){p=new int(x);}
    };
    void f()
    {
        S s1(2), s2;
        S s3 = s1;
        s2 = s1;
        *s1.p=3;
        cout << *s1.p << ' '<< *s2.p << ' ' << *s3.p << endl;//3 3 3
    }
    

    很明显这不是我们想要的,我们想让不同的对象的值不互相影响,此时需要实现深复制,见下例。

    class S
    {
        public:
        int *p;
        S(int x=0){p=new int(x);}
        S(const S& rhs)
        {
            p = new int(*rhs.p);
        }
        const S& operator=(const S& rhs)    //rhs=right-hand side
        {
            if (this != &rhs)   //检查是否复制自身 
                *p = *rhs.p;
            return *this;
        }
    };
    void f()
    {
        S s1(2), s2;
        S s3 = s1;
        s2 = s1;
        *s1.p=3;
        cout << *s1.p << ' '<< *s2.p << ' ' << *s3.p << endl;   //3 2 2
    }
    
posted @ 2014-04-06 20:29  Norcy  阅读(4115)  评论(0编辑  收藏  举报