标签:
拷贝构造
零初始化:类型名(),对于基本类型而言是数值0,对于类或者结构类型而言是匿名对象。
当用一个同类对象初始化一个同类新对象时,调用的自然是拷贝构造函数。一个类如果没有定义拷贝构造函数,编译器会自动产生一个构造函数,内容是逐个复制对于的成员。这一般可以满足程序的需求。如果其中有指针成员指向动态内存的时候两个对象指针成员都会指向相同地方,两个对象释放时都会delete这块内存 从而导致错误。要避免这个问题需要自己来写拷贝构造函数,让每个对象的指针成员各自指向一片动态内存,把旧对象中的数据复制过去。让两片动态内存中的数据相同。
#include<iostream> using namespace std; typedef int T; class A{//数组类,封装和增强数组的功能 T* a; int len; public: A(int n,T init = T()):a(new T[n]){ //零初始化 for (int i = 0;i<n;i++) a[i] = init; len = n; cout<<"创建数组:"<<a <<","<< len << "个元素。" << init <<endl; } ~A(){ cout<<"释放数组:"<< a <<endl; delete[] a; a =NULL; } T& at(int idx){//返回引用 if(idx<0||idx>=len) { cout<<idx<<"超出范围!"<<endl; throw idx;//越界异常结束程序 } else return a[idx]; } int size(){return len;} void resize(int newsize,const T& val=T()){ if (newsize<=len) len = newsize;//缩短在原地就够 else{//加长得换地方 T* np = new T[newsize];//申请新空间 for (int i = 0;i<len;i++) np[i]=a[i];//复制旧数据 for(int i = len;i<newsize;i++) np[i]=val;//给新增元素赋值 delete[] a;//释放旧空间 a = np;//a指向新空间 len = newsize;//记录新大小 } } void print(){ for (int i = 0;i<len;i++) cout<<a[i]<<" "; cout<<endl; } void fill(const T& start,const T& step=T()){//step填充从start开始,步长为step(默认0) for (int i=0;i<len;i++) a[i] = start + step*i; } //过滤数组中的偶数显示出来,返回原来的数组 A filter(A arr){//filter(x) 新建对象arr,用x来初始化arr,调用拷贝构造函数A(const A& r),参数为x for(int i = 0;i<arr.size();i++) if (arr.at(i)%2 == 0) cout << arr.at(i) << " "; cout<< endl; return arr;//返回值对象用arr初始化 } /*编译器自动产生的构造函数样式,会有同一片内存Delete两次的问题 A (const A& r){//r是x的引用(同一体) //拷贝构造函数:实参是个A类型的旧对象 a=r.a;//新对象的a跟x的a指向同一片内存 len=r.len; } */ A (const A& r){//r是x的引用(同一体) //拷贝构造函数:实参是个A类型的旧对象 len = r.len; a = new T[len]; for(int i = 0;i<len;i++) a[i] = r.a[i]; cout<<a<<"创建数组对象复制"<<r.a<<endl; } }; int main() { A x(10);//创建数组对象 x.fill(11,1);//填充11~20 x.print();//显示11~20 x.filter(x).print();//显示偶数 //print 里有个 A arr() system("pause"); return 0; }
运行结果:
标签:
原文地址:http://www.cnblogs.com/visions/p/5456895.html