设为首页 加入收藏

TOP

C++ Primer笔记9_构造函数_拷贝构造(深拷贝与浅拷贝)
2015-07-24 06:37:55 来源: 作者: 【 】 浏览:61
Tags:Primer 笔记 构造 函数 拷贝

1.构造函数:


>构造函数是一个特殊的、与类同名的成员函数,用于给每个成员设置适当的初始值。

  1. >构造函数不能有返回值,函数名与类名相同。

  2. >缺省构造函数时,系统将自动调用该缺省构造函数初始化对象,缺省构造函数会将所有数据成员都初始化为零或 空。缺省构造函数是不带参数的构造函数。

  3. >创建一个对象时,系统自动调用构造函数。


    构造函数的特点:

    1.构造函数可以重载,传入什么实参决定调用不同版本的构造函数。

    2.构造函数不能声明为const 、也不能声明为virtual;(析构函数可以)

    3.一个类如果自定义了一个构造函数,编译器就不会生成默认构造函数。

    4.只有构造函数才有类似初始化列表的形式来初始化成员变量(特别是const成员变量只能在初始化列表中初始化)


    例子:

    #include 
        
         
    #include 
         
           class Person { public: Person();//默认的构造函数 Person(int n, const string &str);//构造函数的重载 private: int age; string *name; }; 
         
        


    2.拷贝构造


    先介绍一下深拷贝浅拷贝

    >浅拷贝: 指的是在对象复制时,只对对象中的数据成员进行简单的赋值;默认拷贝构造函数执行的也是浅拷贝。 大多情况下“浅拷贝”已经能很好地工作了,但是一旦对象存在了动态成员,那么浅拷贝就会出问题了。

    >深拷贝:当类的成员变量有指针类型时,拷贝对象时应该为指针变量重新分配好空间,避免浅拷贝中只拷贝指针的 值,使得两个指针指向同一块内存空间。


    浅拷贝缺陷例子:

    #include 
        
         
    #include 
         
           using namespace std; class Person { public: Person(); Person(int n, const string &str);//构造函数重载 ~Person(); private: int age; string *name; }; Person::Person():age(0), name(NULL)//构造函数初始化列表,定义时不必写! { cout << "Default Person" << endl; } Person::Person(int n, const string &str):age(n), name(new string(str)) { cout << "Init Person" << endl; } Person::~Person() { if(name) { cout << "~Person " << "name: " << *name << " age: " << age << endl; } delete name; } int main() { Person p1(10, string("SCOTT")); Person p2 = p1; return 0; } 
         
        

    运行结果:

    Init Person
    ~Person name: SCOTT age: 10
    Segmentation fault (core dumped)

    程序崩溃原因:

    p2由p1初始化而得到,由于我们没有自定义拷贝构造函数,所以调用的是默认的拷贝构造函数,属于浅拷贝,只对name的值进行了拷贝;p1与p2中的name指针指向同一个new空间,最后调用析构函数时,会造成两次delete而出现段错误。

    如下图所示:

    \

    \


    解决方法:自定义拷贝构造函数! 达到深拷贝的效果

    深拷贝例子:<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">#include #include using namespace std; class Person { public: Person(); Person(int n, const string &str); Person(const Person &n); ~Person(); private: int age; string *name; }; Person::Person():age(0), name(NULL) { cout << "Default Person" << endl; } Person::Person(int n, const string &str):age(n), name(new string(str)) { cout << "Init Person" << endl; } //自定义拷贝构造函数 Person::Person(const Person &n) { if(n.name) { name = new string(*n.name); age = n.age; } } Person::~Person() { if(name) { cout << "~Person " << "name: " << *name << " age: " << age << endl; } delete name; } int main() { Person p1(10, string("SCOTT")); Person p2 = p1; return 0; }

    运行结果:

    Init Person

    ~Person name: SCOTT age: 10

    ~Person name: SCOTT age: 10
    没有出现段错误,由此可见,上述解决方案可行。





】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇leetcode――Add Two Numbers 两.. 下一篇Leetcode Pow(x, n)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: