继承是怎样与动态内存分配进行互动的呢?如果基类采用了动态内存分配,并重新定义了赋值和复制构造函数,这将怎样影响派生类的实现呢?这个是取决于派生类的派生类的属性,如果派生类也使用了动态内存分配,那么就有一些技巧需要注意了。
第一种情况:派生类不使用new ,那么就没有必要为派生类定义显式析构函数、复制构造函数、赋值运算符。派生类写成下面这样。。。 就不需要做很多麻烦的事情,它没有使用new。
class lacksDMA:public baseDMA
{
private:
char color[40];
public:
........
}
第二种情况:派生类使用了new。
写成这样的派生类:
class hasDMA:public baseDMA
{
private:
char *style ;//use new in constructor
public:
........
}
在这种情况下,必须为派生类定义显式析构函数、复制构造函数、赋值运算符。
例子代码如下:
dma.h
#pragma once
#include <iostream>
//Base Class use DMA(动态内存分配)
class baseDMA
{
private:
char* label;
int rating;
public:
baseDMA(const char * l="null",int r=0);//构造函数
baseDMA(const baseDMA & rs); //复制构造函数
virtual ~baseDMA(); //析构函数
baseDMA& operator=(const baseDMA& rs);//赋值运算符
friend std::ostream& operator<<(std::ostream & os,const baseDMA & rs);
};
//derived class without DMA
// no destructor needed
//uses implicit copy constructor
//uses implicit assignment operator
class lacksDMA:public baseDMA
{
public:
lacksDMA(const char * c="blank",const char * l="null",int r=0);
lacksDMA(const char * c,const baseDMA & rs);
friend std::ostream& operator<<(std::ostream & os,const lacksDMA & rs);
private:
enum {COL_LEN=40};
char color[COL_LEN];
};
//derived class with DMA
class hasDMA :public baseDMA
{
private:
char* style;
public:
hasDMA(const char * s="none",const char * l="null",int r=0);//默认的构造函数
hasDMA(const char* s,const baseDMA & rs);//拷贝构造函数
hasDMA(const hasDMA & hs);//拷贝构造函数
~hasDMA();
hasDMA& operator=(const hasDMA& hs);
friend std::ostream& operator<<(std::ostream& os, const hasDMA& rs);
};
dma.cpp
#pragma warning(disable:4996)//这样可以 使得使用std::strcpy() 不报错
#include "dma.h"
#include <cstring>
//baseDMA methods
baseDMA::baseDMA( const char* l, int r)
{
label = new char[std::strlen(l)+1];
std::strcpy(label,l);//将l中的内容复制到label中
//strcpy_s(label, l);//将l中的内容复制到label中
rating = r;
}
baseDMA::baseDMA(const baseDMA& rs)
{
label = new char[std::strlen(rs.label)+1];
std::strcpy(label, rs.label);
rating = rs.rating;
}
baseDMA::~baseDMA()
{
delete[] label;
}
baseDMA& baseDMA::operator=(const baseDMA& rs)
{
if (this == &rs)
return *this;
delete[] label;
label = new char[std::strlen(rs.label) + 1];
std::strcpy(label, rs.label);
rating = rs.rating;
return *this;
}
std::ostream& operator<<(std::ostream& os, const baseDMA& rs)
{
os << "Label: " << rs.label << std::endl;
os << "Rating: " << rs.rating << std::endl;
return os;
}
//lackDMA methods lacksDMA 比基类多了两个私有成员 enum {COL_LEN=40} 和char color[COL_LEN]
lacksDMA::lacksDMA(const char* c, const char* l, int r) :baseDMA(l, r)
{
std::strncpy(color,c,39);
color[39] = '\0';//这是最后一个元素
}
lacksDMA::lacksDMA(const char* c, const baseDMA& rs):baseDMA(rs)
{
std::strncpy(color,c,COL_LEN-1);//拷贝一定数量的字符串到前面的字符串
color[COL_LEN - 1] = '\0';
}
std::ostream & operator<<(std::ostream& os, const lacksDMA & ls)
{
os << (const baseDMA &)ls;
os << "Color: " << ls.color << std::endl;
return os;
}
//hasDMA methods 该类比基类多了一个 char * style
hasDMA::hasDMA(const char* s, const char* l, int r):baseDMA(l,r)
{
style = new char[std::strlen(s) + 1];
std::strcpy(style,s);
}
hasDMA::hasDMA(const char* s, const baseDMA & rs) : baseDMA(rs)
{
style = new char[std::strlen(s) + 1];
std::strcpy(style, s);
}
hasDMA::hasDMA(const hasDMA& hs):baseDMA(hs)//invoke base class copy constructor 调用基类的拷贝构造函数
{
style = new char[std::strlen(hs.style)+1];
std::strcpy(style, hs.style);
}
hasDMA::~hasDMA()
{
delete[] style;
}
hasDMA& hasDMA::operator=(const hasDMA& hs)
{
if (this == &hs)
return *this;
baseDMA::operator=(hs);//copy base portion 拷贝基类的部分
delete[] style;//prepare for the new style ;
style = new char[std::strlen(hs.style)+1];
std::strcpy(style,hs.style);
return *this;
}
std::ostream& operator<<(std::ostream& os, const hasDMA& hs)
{
// type cast to match operator <<(ostream & ,const baseDMA &) 这里做了一个强制转换,转换为父类
os << (const baseDMA &)hs;
os << "Style: " << hs.style << std::endl;
return os;
}
主函数就是使用了上面声明的类,然后做了个输出。
usedma.cpp
// Chapter13.7InheritenceAndDMA_usedma.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include "dma.h"
int main()
{
// std::cout << "Hello World!\n";
using std::cout;
using std::endl;
baseDMA shirt("Portabelly",8);
lacksDMA balloon("red","Blimpo",4);
hasDMA map("Mercator","Buffalo Keys",5);
cout << "Displaying BaseDMA object:\n";
cout << shirt << endl;
cout << "Displaying lacksDMA object:\n";
cout << balloon << endl;
cout << "Displaying hasDMA object:\n";
cout << map << endl;
lacksDMA balloon2(balloon);
cout << "Result of lacksDMA copy:\n";
cout << balloon2 << endl;
hasDMA map2;
map2 = map;
cout << "Result of hasDMA assignment:\n";
cout << map2 << endl;
return 0;
}
运行结果略。