• 每天一道算法题(3)——含有指针元素的模板类


    1.定义

            倘若没有拷贝构造函数,编译器自动生成的构造拷贝函数或者拷贝运算符的重载函数。在编译器生成的缺省的构造拷贝函数和拷贝运算符的重载函数,对指针实行的是按位拷贝,仅仅只是拷贝指针的地址,而不会拷贝指针的内容。因此在执行完前面的代码之后,指针指向同一地址。当A或者B中任意一个结束其生命周期调用析构函数时,程序就会不可避免地崩溃。因此在此种情况中,一般手动定义拷贝构造函数和重载赋值函数。

            还有另外一种解决方法,即为还可以保存究竟有多少个指针指向该数据。只有当没有任何指针指向该数据的时候才可以被删除。这种思路通常被称之为引用计数技术。具体见参考1


    #include"iostream"
    using namespace std;
    template<typename T>
    class myArray{
    	T* data;
    	unsigned int size;
    public: 
    	  
    	  myArray(unsigned int s=0):size(s),data(NULL){
    		if(s>0)
    			data=new T[size];
    	  }
    	  myArray(myArray& temp):size(temp.size),data(NULL){//拷贝构造函数
    		  if(temp.size>0){
    			  data=new T[size];
    			  for(int i=0;i<size;i++)
    				    data[i]=temp.data[i];
    		  }
    	  }
    	  const& myArray operator = (myArray& temp){//重载赋值运算符
    		  if(this==&temp)
    			  return *this;
    
    		  if(data!=NULL){
    			  delete []data;
    			  data=NULL;
    		  }
    
    		  size=temp.size;
    		  if(size>0){
    			  data=new T[size];
    			  for(int i=0;i<size;i++)
    				  data[i]=temp.data[i];
    		  }
    		  return *this;
    	  }
    
    	 void setValue(unsigned int index, const T value)
             {
                if(index < size)
                      data[index] = value;
             }
      
    	  T getValue(unsigned int index) const
                   if(index>=0&&index < size)
    				return data[index];         
             }
    
    	  unsigned int getSize() const{
    		  return size;
    	  }
    
    	 friend ostream& operator<<( ostream& out,const myArray& m){//重载输出运算符
    		 unsigned int size=m.getSize();
    
    		  if(size>0)
    			  for(int i=0;i<size;i++)
    				  out<<m.getValue(i)<<endl;
    
    		  return out;
    	  }
    
    	  ~myArray(){
    		  if(data)
    		      delete []data;
    	  }
    
    };

    注意:1.任何情况下,data应该有指向,使用delete后,也要使指针置空。
             2.友元函数重载无法使用形参私有成员,但是非友元函数却可以。原因见下面
             3.使用const&作为“=”重载的返回类型,保证了无法连续赋值,即(A=B)=C或者A=B=C;


    2.其它

       2.1输入输出流重载

            friend istream& operator>>(istream& in, F& f){ return in;}   //输入运算符重载标准格式
               friend ostream& operator<<(ostream& out, const F&)(return out;)  //输出运算符的标准重载格式.

            为什么必须定义为友元函数。定义为成员函数隐含this指针,那么只有对应的类对象才能调用,但是<<和>>调用的对象肯定只能是cout或者cin,即不能定义为成员函数了。只有定义成友元,才可以将cin,cout作为一个参数传入重载的操作符函数。返回引用便于实现连续输出或者输入。注意>>形参不为const类型。


      2.2拷贝构造函数

           什么可以直接使用形参的私有成员

             访问限制标识符是针对类作用而不是针对一个类的不同对象,只要同属一个类,则不用区分是公有私有。具体见参考2

           为什么形参规定为引用类型
               1)引用比较高效
                   如果形参是对象类型的,则需要实例化即对整个对象进行拷贝,效率不高,很不划算。如果形参是指针类型的,从编译的角度来 程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。
               2)形参为对象类型行不通
                  拷贝构造函数也是构造函数。如果形参是对象,在被调用时形参也需要实例化(构造,形参 = 实参 。即调用拷贝构造函数) 。之后调用拷贝构造函数的形参又要实例化,则又调用拷贝构造函数,产生无穷递归。
    具体见参考3

          





    参考

             1.每天一道算法题15 含有指针成员的类的拷贝

             2.C++ 的一个问题的理解(私有变量成员)

             3.c++复制构造函数的形参为什么规定为引用类型?

  • 相关阅读:
    Installation request for topthink/think-captcha ^3.0 -> satisfiable by topthink/think-captcha[v3.0.0].
    /etc/sudoers配置错误导致的nova-api等异常
    修改ssh默认端口导致的虚拟机resize失败
    ansible自动化测试云平台多个网络角色间带宽(shell模块调用iperf)
    nova的服务心跳机制和服务状态监控机制的实现
    时间不同步导致的nova,cinder服务一会up一会down的来回跳跃
    利用ansible部署keeplived和haproxy集群
    利用ansible检测网络连通性(多个网段多IP)
    通过ansible安装etcd集群
    部署k8s statefulset
  • 原文地址:https://www.cnblogs.com/engineerLF/p/5393048.html
Copyright © 2020-2023  润新知