如何注册公司网站免费注册,婚纱网站手机网站,wordpress没法登陆,东圃网站建设介绍和示例
拷贝构造函数是一种特殊的构造函数#xff0c;它在创建对象时#xff0c;是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于#xff1a; 通过使用另一个同类型的对象来初始化新创建的对象。 复制对象把它作为参数传递给函数。 复制对象…介绍和示例
拷贝构造函数是一种特殊的构造函数它在创建对象时是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于 通过使用另一个同类型的对象来初始化新创建的对象。 复制对象把它作为参数传递给函数。 复制对象并从函数返回这个对象。
如果在类中没有定义拷贝构造函数编译器会自行定义一个。如果类带有指针变量并有动态内存分配则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下
//在这里obj 是一个对象引用该对象是用于初始化另一个对象的。
classname (const classname obj) {// 构造函数的主体
}
示例
#include iostreamusing namespace std;class Line
{public:int getLength( void );Line( int len ); // 简单的构造函数Line( const Line obj); // 拷贝构造函数~Line(); // 析构函数private:int *ptr;
};// 成员函数定义包括构造函数
Line::Line(int len)
{cout 调用构造函数 endl;// 为指针分配内存ptr new int;*ptr len;
}Line::Line(const Line obj)
{cout 调用拷贝构造函数并为指针 ptr 分配内存 endl;ptr new int;*ptr *obj.ptr; // 拷贝值
}Line::~Line(void)
{cout 释放内存 endl;delete ptr;
}
int Line::getLength( void )
{return *ptr;
}void display(Line obj)
{cout line 大小 : obj.getLength() endl;
}// 程序的主函数
int main( )
{Line line(10);display(line);return 0;
}
编译执行结果 下面的实例对上面的实例稍作修改通过使用已有的同类型的对象来初始化新创建的对象
#include iostreamusing namespace std;class Line
{public:int getLength( void );Line( int len ); // 简单的构造函数Line( const Line obj); // 拷贝构造函数~Line(); // 析构函数private:int *ptr;
};// 成员函数定义包括构造函数
Line::Line(int len)
{cout 调用构造函数 endl;// 为指针分配内存ptr new int;*ptr len;
}Line::Line(const Line obj)
{cout 调用拷贝构造函数并为指针 ptr 分配内存 endl;ptr new int;*ptr *obj.ptr; // 拷贝值
}Line::~Line(void)
{cout 释放内存 endl;delete ptr;
}
int Line::getLength( void )
{return *ptr;
}void display(Line obj)
{cout line 大小 : obj.getLength() endl;
}// 程序的主函数
int main( )
{Line line1(10);Line line2 line1; // 这里也调用了拷贝构造函数display(line1);display(line2);return 0;
}
编译执行结果 拷贝构造函数几个原则
拷贝构造函数是一种特殊的构造函数具有单个形参该形参常用const修饰是对该类类型的引用。当定义一个新对象并用一个同类型的对象对它进行初始化时将显示使用拷贝构造函数。当该类型的对象传递给函数或从函数返回该类型的对象时将隐式调用拷贝构造函数。
C支持两种初始化形式
拷贝初始化 int a 5; 和直接初始化 int a(5); 对于其他类型没有什么区别对于类类型直接初始化直接调用实参匹配的构造函数拷贝初始化总是调用拷贝构造函数也就是说
A x(2); //直接初始化调用构造函数
A y x; //拷贝初始化调用拷贝构造函数
必须定义拷贝构造函数的情况
只包含类类型成员或内置类型但不是指针类型成员的类无须显式地定义拷贝构造函数也可以拷贝有的类有一个数据成员是指针或者是有成员表示在构造函数中分配的其他资源这两种情况下都必须定义拷贝构造函数。
什么情况使用拷贝构造函数
类的对象需要拷贝时拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数
1一个对象以值传递的方式传入函数体2一个对象以值传递的方式从函数返回3一个对象需要通过另外一个对象进行初始化。
关于为什么当类成员中含有指针类型成员且需要对其分配内存时一定要有总定义拷贝构造函数
默认的拷贝构造函数实现的只能是浅拷贝即直接将原对象的数据成员值依次复制给新对象中对应的数据成员并没有为新对象另外分配内存资源。
这样如果对象的数据成员是指针两个指针对象实际上指向的是同一块内存空间。
在某些情况下浅拷贝回带来数据安全方面的隐患。
当类的数据成员中有指针类型时我们就必须定义一个特定的拷贝构造函数该拷贝构造函数不仅可以实现原对象和新对象之间数据成员的拷贝而且可以为新的对象分配单独的内存资源这就是深拷贝构造函数。
如何防止默认拷贝发生
声明一个私有的拷贝构造函数这样因为拷贝构造函数是私有的如果用户试图按值传递或函数返回该类的对象编译器会报告错误从而可以避免按值传递或返回对象。
总结
当出现类的等号赋值时会调用拷贝函数在未定义显示拷贝构造函数的情况下系统会调用默认的拷贝函数——即浅拷贝它能够完成成员的一一复制。当数据成员中没有指针时浅拷贝是可行的。但当数据成员中有指针时如果采用简单的浅拷贝则两类中的两个指针将指向同一个地址当对象快结束时会调用两次析构函数而导致指针悬挂现象。所以这时必须采用深拷贝。
深拷贝与浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间来储存数据从而也就解决了指针悬挂的问题。简而言之当数据成员中有指针时必须要用深拷贝。