现在的位置: 首页 > 综合 > 正文

继承 之 动态内存分配

2014年02月13日 ⁄ 综合 ⁄ 共 1525字 ⁄ 字号 评论关闭

假设基类使用动态内存分配,并重新定义了赋值和复制构造函数
class class_a
{
 private:
    char* a;
    int rating;
 public:
    class_a(const char* l="null",int r=0);
    class_a(const class_a & rs);
    virtual ~class_a();
    class_a & operator=(const class_a & rs);
    ...
};

 

声明中包含了构造函数使用new时需要的特殊方法:析构函数、复制构造函数和重载赋值操作符。详情查看<<关于类隐式成员函数>>

 

当派生类使用new
class class_b:public class_a
{
 private:
    char* b; //use new in constructors
 public:
    ...
};

 

这种情况下,必须为派生类定义显示析构函数、复制构造函数和赋值操作符。

 

1.析构函数
    派生类析构函数自动调用基类的析构函数,故其自身的职责是对派生类构造函数执行工作的进行清理。因此,class_b析构函数必须释放指针 b 管理的内存,并依赖于class_a的析构函数来释放指针 a 管理的内存。
class_a::~class_a(){delete[] a;}
class_b::~class_b(){delete[] b;}

 

2.复制构造函数
基类定义的复制构造函数如下:
class_a(const class_a & rs)
{
  a= new char[std::strlen(re.a)+1];
  std::strcpy(a,rs.a);
  rating = rs.a;
}

 

由于class_b的复制构造函数只能访问class_b的数据,因此它必须调用class_a的复制构造函数来处理共享的class_a数据:
class_b::class_b(const class_b & hs):class_a(hs)
{
  b = new char[std::strlen(hs.b)+1]
  std::strcpy(b,hs.b);
}

 

3.赋值操作符
基类定义的赋值操作符如下:
class_a & class_a::operator= (const class_a & rs)
{
 if(this == &rs)
    return *this;
 delete [] a;
 a = new char[std::strlen(rs.a)+1];
 std::strcpy(a,rs.a);
 rating=rs.rating;
 return *this;
}

 

派生类的显示赋值操作符必须负责所有继承的class_a基类对象的赋值,可以通过显示调用基类赋值操作符来完成:
class_b & class_a::operator= (const class_b & hs)
{
 if(this == &rs)
    return *this;
 class_a::operator=(hs);
 b = new char[std::strlen(hs.b)+1];
 std::strcpy(b,hs.b);
 return *this;
}


class_a::operator=(hs) 使用函数表示法,而不是操作符表示法,可以使用作用域解析操作符,从而使得赋值操作符被正确的调用。

      

       当基类和派生类都采用动态内存分配时,派生类的析构函数、复制析构函数以及赋值操作符都必须使用相应的基类方法来处理基类元素。对于析构函数,这是自动完成的;对于复制构造函数,这是通过在初始化成员列表中调用基类的复制构造函数来完成的;如果不这样做,将自动调用基类的默认构造函数。对于赋值操作符,是通过使用作用域解析操作符显示地调用基类的赋值操作符来完成的。

抱歉!评论已关闭.