zoukankan      html  css  js  c++  java
  • 含动态分配内存的类的声明和定义以及继承

              假设基类base,派生类derive1,derive2. 其中前2者含有指针成员(自动分配内存),后者不含。

    1.声明

             三者声明如下:

    #include"iostream"
    #include"string"
    using namespace std;
    //含有动态分配内存的基类
    class base{
    public:
    	base(const char* pointer=NULL);
    	base(const base&);
    	base& operator=(const base&);
    	friend ostream& operator <<(ostream& ,const base&);
    	virtual ~base(){
    	   if(p)
    	    delete []p;
    	}
    private:
    	char* p;
    };
    
    //含有动态分配内存的派生类
    class derive1 :public base{
    	public:
    	derive1(const char* pointer1=NULL,const char* pointr2=NULL);
    	derive1(derive1&);
    	derive1& operator=(const derive1&);
    	friend ostream& operator <<(ostream&,const derive1&);
    	~derive1(){
    	   if(q)
    	    delete []q;
    	}
    private:
    	char* q;
    };
    
    //不含动态分配内存的派生类
    class derive2 :public base{
    	public:
    	derive2(const string& ,const char* pointer=NULL);
    	derive2(const derive2&);
    	friend ostream& operator <<(ostream&,const derive2&);
    private:
    	string q;
    };
      

         对于基类base:                                                
              (1)需要重载拷贝构造函数和赋值运算符。
              (2)析构函数声明为虚函数。当派生类也具有自动分配内存时,基类指针指向派生类对象时,将调用派生类的析构函数(继而调用基类析构函数)释放所有内存。这样避免了内存泄露


         对于derive1:public base的情况          (1)需要重载拷贝构造函数,且显式调用基类拷贝构造函数构造基类部分;
              (2)需要重载赋值运算符,且其中,使用base::operator=(d);显式地调用基类赋值运算符复制基类部分
              (3)倘若需要重载输出运算符。其中需要显式的使用类型转换out<<(const base&)d;输出基类数据,然后再输出派生类的数据


         对于derive2:public base的情况: 
             (1)不需要重载拷贝构造函数,其中对于基类的自动分配内存的拷贝自动调用基类中已经重载的拷贝构造函数。
             (2)需要在输出运算符重载时,显式转换且输出基类数据。


    2.定义

    #include"declaration.h"
    /************************基类base定义*****************************/
    base::base(const char* pointer){//构造函数
    	if(!pointer)
    		p=NULL;
    	else{
    	   p=new char[strlen(pointer)+1];
    	   strcpy(p,pointer);
    	}
    }
    base::base(const base& b){//拷贝构造函数
    	p=new char[strlen(b.p)+1];
    	strcpy(p,b.p);
    }
    base& base::operator=(const base& b){//重载赋值函数
    	if(this==&b)
    		return *this;
    
    	if(p){
    		delete[]p;
    		p=NULL;
    	}
    	p=new char[strlen(b.p)+1];
    	strcpy(p,b.p);
    	return *this;
    }
    ostream& operator <<(ostream& out,const base& b){//重载输出运算符
    	if(b.p)
    		cout<<b.p<<endl;
    	return out;
    }
    
    
    /************************含有动态分配内存的派生类derive1的定义*****************************/
    derive1::	derive1(const char* pointer1,const char* pointer2):base(pointer1){//构造函数
    	if(!pointer2)
    		q=NULL;
    	else{
    	   q=new char[strlen(pointer2)+1];
    	   strcpy(q,pointer2);
    	}
    }
    derive1:: derive1(derive1& d):base(d){//拷贝构造函数
    	q=new char[strlen(d.q)+1];
    	strcpy(q,d.q);
    }
    derive1& derive1::operator=(const derive1& d){//重载赋值运算符
    	if(this==&d)
    		return *this;
    
    	base::operator=(d);
    	if(q){
    		delete[]q;
    		q=NULL;
    	}
    	q=new char[strlen(d.q)+1];
    	strcpy(q,d.q);
    	return *this;
    }
    
    ostream& operator <<(ostream& out,const derive1& d){//重载输出运算符
        out<<(const base&)d<<d.q<<endl;
    	return out; 
    }
    
    /************************不含有动态分配内存的派生类derive1的定义*****************************/
    derive2:: derive2(const string& s,const char*pointer):base(pointer),q(s){}//构造函数
    ostream& operator <<(ostream& out,const derive2&d){//重载输出运算符
    	out<<(const base&)d<<d.q<<endl;
    	return out;
    }

           注意:编译时,只需包含声明文件“declaration.h”即可,否则会显示link2005的重定义错误。





  • 相关阅读:
    js 百度地图和谷歌地图的选择
    angular4 自定义表单验证Validator
    推荐20个很有帮助的 Web 前端开发教程
    前端同学大福利,最全的面试题目整理
    前端开发:如何写一手漂亮的 Vue
    推荐20个很有帮助的 Web 前端开发教程
    面试分享:一年经验初探阿里巴巴前端社招
    想成为一个高效的Web开发者吗?来看看大牛分享的经验吧~ #精选JAVASCRIPT前端开发
    初学者Web介绍一些前端开发中的基本概念用到的技术
    Web设计新手应知道的10个锦囊妙计
  • 原文地址:https://www.cnblogs.com/engineerLF/p/5393038.html
Copyright © 2011-2022 走看看