类对象结构

来源:互联网 发布:js date对象 编辑:程序博客网 时间:2024/05/22 08:04

前言:对于类的一些构造之前有一定的了解,但到具体的技术细节,总会有些纰漏,经过多方查阅,有了一些新的感悟,在这里做一个总结,方便之后翻阅。
首先声明一个简单类型MyClass,做测试用:

#include <stdio.h>#include <iostream>using namespace std;class MyClass{private:    int i; //实例对象,用于模拟类信息    int *p; //实例指针对象,用于模拟类信息public:    static int count; //静态变量,用于统计实际产生多少个对象    MyClass(int i)    {        cout << "Enter MyClass Creater:" << this << endl;        count++; //每生成一个对象,统计count就+1        p = new int;        this->i = i;    }    ~MyClass()    {        cout << "Enter MyClass Deleter:" << this << endl;        count--; //每销毁一个对象,统计count就-1        if (NULL != p)        {            delete p;        }    }    MyClass(const MyClass& myObject)    {        cout << "Enter MyClass Coper:" << this << endl;        this->i = myObject.i;        count++; //复制对象时,统计数+1        p = new int;        *p = *(myObject.p);    }    MyClass & operator=(const MyClass& myObject)    {        cout << "Enter MyClass Assigner:" << this << endl;        this->i = myObject.i; //对象赋值时,统计数不需要变动        return *this;    }};int MyClass::count = 0;

一、当对象通过形参传入其他函数中时(按照注释的顺序):

MyClass fun01(MyClass myObject) //2)myObject作为形参传入,调用复制构造函数,count=2{    return myObject; //3)return返回时会cope到一个临时变量,进入复制构造函数,count=3,之后因为fun01的myobject在栈上,会调用调用此处的myobject的析构函数,所以count--之后,count=2}int main(){    MyClass myObject(1); //1)count=1    MyClass myObject2 = fun01(myObject); //4)此处没有对象接收函数返回值时,会调用临时变量的析构函数,count=1,    return 0;}//5)此处析构掉栈上的对象main的myObject,count=0

可以想象,当对象参数通过引用的方式传入的时候,由于不会复制对象,所以count最大值只会到2。

二、复制构造函数与赋值构造函数

int main(){    MyClass myObject1(1);    MyClass myObject2=myObject1; //对象myObject2本身不存在,调用复制构造函数,最后是两个对象    MyClass myObject3(1);    MyClass myObject4(2);    myObject4 = myObject3; //对象myObject4本身存在,调用赋值构造函数,最后是两个对象    return 0;}

另外,通过对象初始化的话也是调用复制构造函数(MyClass myObjectx(myObject4))。

三、为什么要重写复制构造函数

class MyClass2{private:    int i; //实例对象,用于模拟类信息    int *p; //实例指针对象,用于模拟类信息public:    static int count; //静态变量,用于统计实际产生多少个对象    MyClass2(int i)    {        cout << "Enter MyClass2 Creater:" << this << endl;        count++; //每生成一个对象,统计count就+1        p = new int;        this->i = i;    }    ~MyClass2()    {        cout << "Enter MyClass2 Deleter:" << this << endl;        count--; //每销毁一个对象,统计count就-1        if (NULL != p)        {            delete p;        }    }};int MyClass2::count = 0;int main(){    MyClass2 myObject5(1);    MyClass2 myObject6 = myObject5; //对象myObject6本身不存在,调用默认复制构造函数,最后是一个对象    return 0;}

编译器会默认生成复制构造函数,但是默认生成的复制构造函数是的按位复制对象(浅复制),并不会生产新的对象(myObject6就是myObject5)。当对象内部含有指针对象(MyClass2的p),造成复制出来的的对象内部的指针类型数据(myObject6->p)和原本对象内部的指针类型数据(myObject5->p)值一致,导致所指向的目标一致(*myObject6->p和*myObject5->p),结果导致第一个对象delete之后,第二个对象重复delete。

另外,默认复制构造函数导致MyClass2::count并不会增加。

所以我们需要创建自定义的复制构造函数进行深复制(参看MyClass)。

之后若有其他关于对象结构的内容,会在此处补充。