关于抽象基类的一道作业题,执行结果老是有问题,麻烦各位指点下

robbiluo 2008-10-27 08:53:10
代码如下:
头文件:
#ifndef ACCTDMA_H_
#define ACCTDMA_H_
#include<iostream>

// Abstract Base Class

class Acctdma
{
private:

char * label;
int rating;

public:

Acctdma(const char * l = "null",int r = 0);
Acctdma(const Acctdma & rs);
virtual ~Acctdma()=0;
virtual Acctdma & operator*() { return *this; }
Acctdma & operator = (const Acctdma & rs);
virtual void View() const;
friend std::ostream & operator<< (std::ostream & os,const Acctdma & rs);
};

// Class Basedma

class Basedma:public Acctdma
{
private:
public:
Basedma(const char * l = "null",int r = 0);

};

// Class Lacksdma

class Lacksdma:public Acctdma
{
private:

char color[40];
public:
Lacksdma (const char * c ,const char * l,int r);
Lacksdma (const char * c,const Acctdma & rs);
void View() const;
friend std::ostream & operator<<(std::ostream & os,const Lacksdma & ls);

};

//Class Hasdma

class Hasdma:public Acctdma
{
private:
char * style;
public:
Hasdma(const char * s ,const char * l,int r );
Hasdma(const char * s,const Acctdma & hs);
Hasdma(const Hasdma & hs);
void View() const;
~Hasdma();
Hasdma & operator = (const Hasdma & hs);
friend std::ostream & operator<<(std::ostream & os,const Hasdma & hs);

};
#endif

类方法:
#include<iostream>
#include<cstring>
#include"acctdma.h"
using namespace std;

//acctdma methods
Acctdma::Acctdma(const char * l,int r)
{
label = new char[std::strlen(l)+1];
std::strcpy(label,l);
rating = r;
}

Acctdma::Acctdma(const Acctdma & rs)
{
label = new char[std::strlen(rs.label) +1];
std::strcpy(label,rs.label);
rating = rs.rating;
}

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

Acctdma & Acctdma::operator = (const Acctdma & 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;
}

void Acctdma:: View() const
{
cout<<"Label: "<<label<<endl;
cout<<"Rating: "<<rating<<endl;
}


std::ostream & operator<<(std::ostream & os,const Acctdma & rs)
{
os<<"Label: "<<rs.label<<endl;
os<<"Rating: "<<rs.rating<<endl;
return os;
}

//Basedma methods
Basedma::Basedma(const char * l, int r) : Acctdma(l,r)
{

}

//Lacksdma methods
Lacksdma::Lacksdma(const char *c , const char *l , int r):Acctdma(l,r)
{
std::strncpy(color,c,39);
color[39]='\0';
}

Lacksdma::Lacksdma(const char *c, const Acctdma &rs):Acctdma(rs)
{
std::strncpy(color ,c,39);
color[39] = '\0';
}

void Lacksdma::View() const
{
Acctdma::View();
cout<<"Color: "<<color<<endl;
}

std::ostream & operator<<(std::ostream & os,const Lacksdma & ls)
{
os<<(const Acctdma &) ls;
os<<"Color: "<<ls.color<<endl;
return os;
}

//Hasdma methods

Hasdma::Hasdma(const char *s , const char *l , int r ):Acctdma(l,r)
{
style = new char[std::strlen(s)+1];
std::strcpy(style,s);
}

Hasdma::Hasdma(const char *s, const Acctdma &hs):Acctdma(hs)
{
style = new char[std::strlen(s)+1];
std::strcpy(style,s);
}

Hasdma::Hasdma(const Hasdma &hs):Acctdma(hs)
{
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;
Acctdma::operator=(hs); //copy abstract portion
style = new char[std::strlen(hs.style)+1];
std::strcpy(style,hs.style);
return *this;
}

void Hasdma::View() const
{
Acctdma::View();
cout<<"Style: "<<style<<endl;
}


std::ostream & operator<<(std::ostream & os,const Hasdma & hs)
{
os<<(const Acctdma &) hs;
os<<"Style: "<<hs.style<<endl;
return os;
}




这是执行代码:
#include <iostream>
#include "acctdma.h"
using namespace std;
int main()
{
using std::cout;
using std::endl;
Basedma shirt("Portabelly", 8);
Lacksdma balloon("red", "Blimpo", 4);
Hasdma map("Mercator", "Buffalo Keys", 5);
cout << shirt << endl;
cout << balloon << endl;
cout << map << endl;
Lacksdma balloon2(balloon);
Hasdma map2;
map2 = map;
cout << balloon2 << endl;
cout << map2 << endl;

Acctdma * pts[3];
pts[0] = &shirt;
pts[1] = &balloon;
pts[2] = ↦

for (int i = 0; i < 3; i++)
cout << *pts[i] << endl;
for (int i = 0; i < 3; i++)
pts[i]->View();
return 0;
}

执行出来的结果有问题:
主要是cout << map2 << endl;和for (int i = 0; i < 3; i++) cout << *pts[i] << endl;执行有误。。。麻烦大家看下。。。

...全文
134 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
zsl6658 2008-10-28
  • 打赏
  • 举报
回复
up
太乙 2008-10-28
  • 打赏
  • 举报
回复
再次up~~~
liumingrong 2008-10-28
  • 打赏
  • 举报
回复
或者去掉派生类的operator《,将基类中的改成
std::ostream & operator <<(std::ostream & os,const Acctdma & rs)
{
(&rs)->View();
return os;
}
[Quote=引用 10 楼 liumingrong 的回复:]
而且虚函数地执行是通过指针方式地调用对象的虚函数,
比如这样你才可以看到你想要的结果
for(int i = 0; i < 3; i++)
(&(*pts[i]))->View();
引用 8 楼 liumingrong 的回复:
operator*返回类型就是Acctdma,尽管它可能引用的是派生类,
operator < <并不知情,它不是虚函数,不会动态绑定
引用 6 楼 robbiluo 的回复:
恩,我加了个缺省构造函数,还是不行,那个指针输出应该没有问题,我定了operator *的虚函…
[/Quote]
太乙 2008-10-28
  • 打赏
  • 举报
回复
建议lz以后贴代码贴精要的,要不就先抽象一下~~嘿嘿,照顾一下像我这样的懒人~~
liumingrong 2008-10-28
  • 打赏
  • 举报
回复
而且虚函数地执行是通过指针方式地调用对象的虚函数,
比如这样你才可以看到你想要的结果
for(int i = 0; i < 3; i++)
(&(*pts[i]))->View();
[Quote=引用 8 楼 liumingrong 的回复:]
operator*返回类型就是Acctdma,尽管它可能引用的是派生类,
operator < <并不知情,它不是虚函数,不会动态绑定
引用 6 楼 robbiluo 的回复:
恩,我加了个缺省构造函数,还是不行,那个指针输出应该没有问题,我定了operator *的虚函数啊。。。应该会根据对象来调用
[/Quote]
太乙 2008-10-28
  • 打赏
  • 举报
回复
so long~~我接分~~哈哈~~
xuedaoli 2008-10-28
  • 打赏
  • 举报
回复
问题是你定义的是基类的指针吧,不是特定的子类的对象。
当然调用operator <<的时候,,查找的顺序问题,最先查找的地方当然是基类的内部了,这个可以去C++ Primer书上看下。
多态的问题,再说了竟然你要这个功能,为什么不把operator << 写成虚函数呢?
robbiluo 2008-10-28
  • 打赏
  • 举报
回复
晕了。。。谢了,我突然发现以前有几个赋值函数的问题都是多了个分号。。。嘎嘎
liumingrong 2008-10-28
  • 打赏
  • 举报
回复
你的operator=里面
if(this==&hs);
==》 多写了分号
[Quote=引用 16 楼 robbiluo 的回复:]
其他的解决了,就是cout < < map2 < < endl;有问题,为啥map不能赋值给map2啊。。。
[/Quote]
robbiluo 2008-10-28
  • 打赏
  • 举报
回复
其他的解决了,就是cout << map2 << endl;有问题,为啥map不能赋值给map2啊。。。
liumingrong 2008-10-27
  • 打赏
  • 举报
回复
operator*返回类型就是Acctdma,尽管它可能引用的是派生类,
operator<<并不知情,它不是虚函数,不会动态绑定
[Quote=引用 6 楼 robbiluo 的回复:]
恩,我加了个缺省构造函数,还是不行,那个指针输出应该没有问题,我定了operator *的虚函数啊。。。应该会根据对象来调用
[/Quote]
robbiluo 2008-10-27
  • 打赏
  • 举报
回复
Label: null
Rating: 0
Style: 请按任意键继续. . .

为啥赋值没有成功,还有那个指针输出为啥不会根据指针指向对象来调用方法。。。
robbiluo 2008-10-27
  • 打赏
  • 举报
回复
恩,我加了个缺省构造函数,还是不行,那个指针输出应该没有问题,我定了operator *的虚函数啊。。。应该会根据对象来调用
xiaodongdehome 2008-10-27
  • 打赏
  • 举报
回复
cout < < *pts[i] < < endl;

执行的是:
std::ostream & operator < <(std::ostream & os,const Acctdma & rs)
{
os < <"Label: " < <rs.label < <endl;
os < <"Rating: " < <rs.rating < <endl;
return os;
}
///////////
因为 cout < < *pts[i] < < endl;
生成了 一个临时的Acctdma 类型对象, 所以调用了以上这个函数
------
Hasdma & Hasdma::operator =(const Hasdma & hs)
{
if(this==&hs);
return *this;
Acctdma::operator=(hs); //copy abstract portion
delete [] style; //不加此行 应该有堆内存泄漏问题
style = new char[std::strlen(hs.style)+1];
std::strcpy(style,hs.style);
return *this;
}
------------------
这只是个人的理解.
chlaws 2008-10-27
  • 打赏
  • 举报
回复

//main.cpp
/*
Label: Portabelly
Rating: 8

Label: Blimpo
Rating: 4
Color: red

Label: Buffalo Keys
Rating: 5
Style: Mercator

Label: Blimpo
Rating: 4
Color: red

Label: null
Rating: 0
Style: 请按任意键继续. . .
*/


#include <iostream>
#include <stdlib.h>
#include "acctdma.h"

using namespace std;

int main(int argc, char *argv[])
{
Basedma shirt("Portabelly", 8);
Lacksdma balloon("red", "Blimpo", 4);
Hasdma map("Mercator", "Buffalo Keys", 5);
cout << shirt << endl;
cout << balloon << endl;
cout << map << endl;
Lacksdma balloon2(balloon);
Hasdma map2; //这里Hasdma缺少匹配的构造函数
map2 = map;
cout << balloon2 << endl;
cout << map2 << endl;

Acctdma * pts[3];
pts[0] = &shirt;
pts[1] = &balloon;
pts[2] = ↦

for (int i = 0; i < 3; i++)
cout << *pts[i] << endl;
for (int i = 0; i < 3; i++)
pts[i]->View();

system("PAUSE");
return 0;
}




//acctdma.h
#ifndef ACCTDMA_H_
#define ACCTDMA_H_
#include <iostream>

// Abstract Base Class

class Acctdma
{
private:

char * label;
int rating;

public:

Acctdma(const char * l = "null",int r = 0);
Acctdma(const Acctdma & rs);
virtual ~Acctdma()=0;
virtual Acctdma & operator*() { return *this; }
Acctdma & operator = (const Acctdma & rs);
virtual void View() const;
friend std::ostream & operator << (std::ostream & os,const Acctdma & rs);
};

// Class Basedma

class Basedma:public Acctdma
{
private:
public:
Basedma(const char * l = "null",int r = 0);

};

// Class Lacksdma

class Lacksdma:public Acctdma
{
private:

char color[40];
public:
Lacksdma (const char * c ,const char * l,int r);
Lacksdma (const char * c,const Acctdma & rs);
void View() const;
friend std::ostream & operator <<(std::ostream & os,const Lacksdma & ls);

};

//Class Hasdma

class Hasdma:public Acctdma
{
private:
char * style;
public:
Hasdma():style(NULL){};//注意这里,你缺少了缺省构造函数,因为你已经声明了其他构造函数,那么编译器不会再给你生成缺省构造函数
Hasdma(const char * s ,const char * l,int r );
Hasdma(const char * s,const Acctdma & hs);
Hasdma(const Hasdma & hs);
void View() const;
~Hasdma();
Hasdma & operator = (const Hasdma & hs);
friend std::ostream & operator <<(std::ostream & os,const Hasdma & hs);

};
#endif







//acctdma.cpp
//类方法:
#include <iostream>
#include <cstring>
#include"acctdma.h"
using namespace std;

//acctdma methods
Acctdma::Acctdma(const char * l,int r)
{
label = new char[std::strlen(l)+1];
std::strcpy(label,l);
rating = r;
}

Acctdma::Acctdma(const Acctdma & rs)
{
label = new char[std::strlen(rs.label) +1];
std::strcpy(label,rs.label);
rating = rs.rating;
}

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

Acctdma & Acctdma::operator = (const Acctdma & 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;
}

void Acctdma:: View() const
{
cout <<"Label: " <<label <<endl;
cout <<"Rating: " <<rating <<endl;
}


std::ostream & operator <<(std::ostream & os,const Acctdma & rs)
{
os <<"Label: " <<rs.label <<endl;
os <<"Rating: " <<rs.rating <<endl;
return os;
}

//Basedma methods
Basedma::Basedma(const char * l, int r) : Acctdma(l,r)
{

}

//Lacksdma methods
Lacksdma::Lacksdma(const char *c , const char *l , int r):Acctdma(l,r)
{
std::strncpy(color,c,39);
color[39]='\0';
}

Lacksdma::Lacksdma(const char *c, const Acctdma &rs):Acctdma(rs)
{
std::strncpy(color ,c,39);
color[39] = '\0';
}

void Lacksdma::View() const
{
Acctdma::View();
cout <<"Color: " <<color <<endl;
}

std::ostream & operator <<(std::ostream & os,const Lacksdma & ls)
{
os <<(const Acctdma &) ls;
os <<"Color: " <<ls.color <<endl;
return os;
}

//Hasdma methods

Hasdma::Hasdma(const char *s , const char *l , int r ):Acctdma(l,r)
{
style = new char[std::strlen(s)+1];
std::strcpy(style,s);
}

Hasdma::Hasdma(const char *s, const Acctdma &hs):Acctdma(hs)
{
style = new char[std::strlen(s)+1];
std::strcpy(style,s);
}

Hasdma::Hasdma(const Hasdma &hs):Acctdma(hs)
{
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;
Acctdma::operator=(hs); //copy abstract portion
style = new char[std::strlen(hs.style)+1];
std::strcpy(style,hs.style);
return *this;
}

void Hasdma::View() const
{
Acctdma::View();
cout <<"Style: " <<style <<endl;
}


std::ostream & operator <<(std::ostream & os,const Hasdma & hs)
{
os <<(const Acctdma &) hs;
os <<"Style: " <<hs.style <<endl;
return os;
}
robbiluo 2008-10-27
  • 打赏
  • 举报
回复
可是我每个派生类都分别定义了<<啊。。。
renlang_7 2008-10-27
  • 打赏
  • 举报
回复
问题点:
Acctdma * pts[3];
现象:
指针类型是Acctdma;所以执行下面的<<操作符重载函数的时候,调用的是Acctdma的方法,所以就错误了。
cout < < *pts[i] < < endl;
原因:
因为operator<<不是虚函数,所以不会随着对象的不同调用不同的方法。具体可以查看一下多态的前提。

帅得不敢出门 2008-10-27
  • 打赏
  • 举报
回复
up

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧