注册 登录
编程论坛 C++教室

[讨论]关于一个抽像类继承出几个派生类问题,,

gdzhan 发布于 2007-06-29 22:53, 907 次点击
//dma.h

#ifndef DMA_H
#define DMA_H
#include <iostream>

class dma
{
public:
virtual void view()const = 0;
virtual ~dma();
};

class basedma: public dma
{
public:
basedma(const char* l = "null", int r = 0);
basedma(const basedma& rs);
~basedma();
void view()const;
basedma& operator= (const basedma& rs);
friend std::ostream& operator<< (std::ostream& os, const basedma& rs);
private:
char* label;
int rating;
};

class lackdma: public dma
{
public:
lackdma(const char* c = "blank");
lackdma(const lackdma& rs);
void view()const;
~lackdma(){}
friend std::ostream& operator<< (std::ostream& os, const lackdma& rs);
private:
enum{le = 40};
char color[le];
};

class hasdma: public dma
{
public:
hasdma(const char* s = "done");
hasdma(const hasdma& rs);
~hasdma();
void view()const;
friend std::ostream& operator<< (std::ostream& os, const hasdma& rs);
private:
char* style;
};

#endif
----------------------------------------------------------------------------
#include <iostream>
#include <cstring>

#include "dma.h"

using std::cout;
using std::endl;
using std::strncpy;
using std::strlen;
using std::ostream;

// basedma_class
basedma::basedma(const char* l, int r)
{
int len = strlen(l);
label = new char[len + 1];
strncpy(label, l, len);
label[len] = '\0';
rating = r;
}

basedma::basedma(const basedma& rs)
{
int len = strlen(rs.label);
label = new char[len + 1];
strncpy(label, rs.label, len);
label[len] = '\0';
rating = rs.rating;
}

basedma::~basedma()
{
delete []label;
}

basedma& basedma::operator= (const basedma& rs)
{
if(this == &rs)
return *this;
delete []label;
int len = strlen(rs.label);
label = new char[len + 1];
strncpy(label, rs.label, len);
label[len] = '\0';
rating = rs.rating;

return *this;
}

void basedma::view()const
{
cout << label << " " << rating << endl;
}

ostream& operator<< (ostream& os, const basedma& rs)
{
os << rs.label << " " << rs.rating << endl;
}

//lackdma_class
lackdma::lackdma(const char* s)
{
strncpy(color, s, le);
}

lackdma::lackdma(const lackdma& rs)
{
strcpy(color, rs.color);
}

void lackdma::view()const
{
cout << color << endl;
}

ostream& operator<< (ostream& os, const lackdma& rs)
{
os << rs.color << endl;
return os;
}

//hasdma class
hasdma::hasdma(const char* s)
{
int len = strlen(s);

style = new char[len + 1];
strncpy(style, s, len);
}

hasdma::hasdma(const hasdma& rs)
{
int len = strlen(rs.style);

style = new char[len + 1];
strncpy(style, rs.style, len);
}

void hasdma::view()const
{
cout << style << endl;
}

hasdma::~hasdma()
{
delete []style;
}

ostream& operator<< (ostream& os, const hasdma& rs)
{
os << rs.style << endl;
return os;
}
----------------------------------------------------------------------------
#include <iostream>
#include "dma.h"

using std::cout;
using std::endl;
using std::cin;

const int CLI = 4;
const int LEN = 40;

int main()
{
dma *p_cli[CLI];

int i;
for (i = 0; i < CLI; i++)
{
char temp[LEN];
int tempnum;
double tempbal;
char kind;
cout << "enter cli's name: ";
cin.getline (temp, LEN);
cout << "enter cli's accoutnumber: ";
cin >> tempnum;
cout << "enter 1 for dma account or "
<< "2 for dmaplus account: ";
while (cin >> kind && (kind != '1' && kind != '2'))
{
cout << "enter either 1 or 2: ";
}

if (kind == '1')
{
p_cli[i] = new basedma (temp, tempnum);
}
else
{

cout << "enter the overdraft limit: $";
cout << "enter the interest rate "
<< "as a decimal fraction: ";
p_cli[i] = new lackdma (temp);
}
while (cin.get() != '\n')
{
continue;
}
}

cout << endl;

for (i = 0; i < CLI; i++)
{
p_cli[i]->view();
cout << endl;
}

for (i = 0; i < CLI; i++)
{
delete p_cli[i];
}

cout << "done" << endl;

system("pause");
return 0;
}

没有加上注释,请有耐心看过的师傅们请帮我分析一下,,,(这是C++ PRIMER PLUS里面的一道练习题)
主要是从 dma 这个抽像基类中继承出 basedma,,,lackdam,,,,,hasdma这三个类
然后在测试程序中测试这些类,,

刚自学完这节书的内容,,做这道练习题,编译到最后的时候出现了很多
类似这样的错误:

[Linker error] undefined reference to `dma::~dma()'
[Linker error] undefined reference to `dma::~dma()'
[Linker error] undefined reference to `dma::~dma()'
[Linker error] undefined reference to `dma::~dma()'
[Linker error] undefined reference to `dma::~dma()'
more undefined references to `dma::~dma()' follow
ld returned 1 exit status

这是不是主要是那个抽像基类的析构函数的问题,,
还有就是编译的时候卡巴斯基报这程序有毒,,,,
7 回复
#2
weishj2007-06-29 23:07
去掉
using std::strncpy;
using std::strlen;
,这两个函数不是std名空间中的
你虑基类中的析构函数没有实现,
class dma
{
public:
virtual void view()const = 0;
virtual ~dma(){}
};
这样可以编译通过,不过具体功能没仔细看,你再编译下看

[此贴子已经被作者于2007-6-29 23:08:03编辑过]

#3
huozoo2007-06-30 09:41
看这程序的第一眼,我就没发现using namespace std;
都牛。

[此贴子已经被作者于2007-6-30 9:42:30编辑过]

#4
野比2007-06-30 09:44
std命名空间不是必须的..
#5
aipb20072007-06-30 09:59
别人代码里用了using声明和域操作符指定空间,所以不用using namespace std;

这是可行的。
#6
gdzhan2007-06-30 12:53
以下是引用weishj在2007-6-29 23:07:06的发言:
去掉
using std::strncpy;
using std::strlen;
,这两个函数不是std名空间中的
你虑基类中的析构函数没有实现,
class dma
{
public:
virtual void view()const = 0;
virtual ~dma(){}
};
这样可以编译通过,不过具体功能没仔细看,你再编译下看

谢谢这位师傅,,那个析构函数加上那句可以了,
之前我以为在抽像基类中的所有函数都不可以在基类中写定义的,
所以就全总不写了,

看过之后,想了一下,应该是抽像基类中一样可以定义的, 只是不能实例化,这就是跟其它类不同的地方吧,

不有上面的那两句using std::strncpy;
using std::strlen;
,这两个函数不是std名空间中的,,,
我记得书上说,,,标准库的所有工具都在std这个命名空间里面的,呵呵,,不知道理解得对不对,

还有三楼的那位傅,,看不到程序中有using namespace std;这句,,,
我的理解是: 不一定全部要用这一句,这一句主要是把std里面的所有工具都包含进来,
我的这个程序,,,我用了using指命把需要用到的包含进来,,是可以的,呵,,正如两位版主说的那样,,,

太谢谢楼上的这几位师傅了,,,我才自学不久,,以后还得常常来这请教大家了,发现这论坛很多热心的师傅,

#7
weishj2007-06-30 13:13
strncpy和strlen都是C语言的函数,C++只是沿用了部分C函数,但并没有把它们放在std名空间中.
#8
wfpb2007-06-30 14:18

这些str**函数都在string.h中,你看看这个文件有不有_STD_BEGIN(即:'namespace std{')和_STD_END

1