请教各位学长一个东西,关于继承的,意思简单,但实现有点问题

yangmengxi 2008-01-01 08:28:59
有三个类 图Graph, 点Point, 边Arc
各自派生出三个类 分子Molecule,原子Atom,联系Liaison
另外派生出三个类 网络Reseaux,机器Post ,联络Lien

图类里写一点添加点和边的函数,点类里写一点添加边的函数,边里再写一点添加点的函数等等等等
如果类按照如下定义,分子的实例可以添加机器的实例
//Graph.h
#include<stdio.h>
#include<iostream>
#include <string>
#include <vector>
using namespace std;
class Point;
class Arc;
class Graph{
public:
Graph(){};
Point *points[];
Arc *arcs[];
vector<Sommet*> points;
vector<Arc*> arcs;
virtual void addPoint(Point* s){
points.push_back(s);
cout<<"Point added"<<endl;
}
virtual void addArc (Arc* a) {
arcs.push_back(a);
cout<<"Arc added"<<endl;
}

};
class Point{
public:
Point(){};
Arc * arcs[];
};
class Arete {
public:
Arc(){};
Point * head;
Point *queue;
};


//Chimie
#import "Graph.h"
class Atom;
class Liaison;
class Molecule : virtual public Graph{
public: Molecule(){cout<<"Molecule created"<<endl;};
};
class Atom : virtual public Arc{
public:Atom(){cout<<"Atom created"<<endl;};
};
class Liaison : virtual public Arc{
public Liaison(){cout<<"Liaison created"<<endl;};
};


//Reseaux.cpp
#import "Graph.h"
class Post;
class Lien;
class Reseaux : virtual public Graph{
public:
Reseaux(){cout<<"Reseaux created"<<endl; };
};
class Post : virtual public Arc{
public:
Post(){cout<<" Post created"<<endl;};
};
class Lien : virtual public Arc{
public:
Lien(){cout<<"Lien created"<<endl; };
};

//Test.cpp
#import "Chimie.cpp"
#import "Reseaux.cpp"
int main(){
Molecule * m = new Molecule();
Atom *a = new Atom();
m->addPoint(a);

Post *p = new Post();
m->addPoint(p);// 这条代码会将电脑的实例加到分子的实例上,目的是制止这个操作(分别在编译和运行时)
}
现在目的是要禁止红色这条语句的发生,如何做?
老师的要求是让程序
1.编译时报错
2.运行时报错,并且报错时安全显示

在JAVA里我是用限定类型的模板或者是调用父类并抛出cast异常解决的,但C++就不知道了

前一个好办,在分子和网络里重定义添加的函数就可以了
后一个怎么办?
当然老师不限制手段,是否可以为两个类定义一个共同的接口,然后在这个接口里定义函数什么的?
或者说有什么模式设计的模型适合这个要求的?
另外C++里的类型转换异常如何抛出?

小弟刚开始C++,诚意请各位老鸟指点一二。
...全文
211 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangmengxi 2008-01-06
  • 打赏
  • 举报
回复
大家帮忙想想啊 ,多谢
ltc_mouse 2008-01-05
  • 打赏
  • 举报
回复
个人感觉模板是编译时的一种静多态机制。希望使用模板,是老师的一个建议吗?
tjltail 2008-01-05
  • 打赏
  • 举报
回复
没有is-A的语义,就不应该用继承。这样的设计从一开始就是有问题的。

---------------------------------------------------
那倒不一定,继承有实现继承和接口继承
没有is_a的关系完全可以用private继承
yangmengxi 2008-01-05
  • 打赏
  • 举报
回复
是的,而且要编译时,以及,运行时报错,呵呵
yangmengxi 2008-01-04
  • 打赏
  • 举报
回复
还是没有人愿意指教吗?再顶
Jim_King_2000 2008-01-03
  • 打赏
  • 举报
回复
没有is-A的语义,就不应该用继承。这样的设计从一开始就是有问题的。
yangmengxi 2008-01-03
  • 打赏
  • 举报
回复
这个东西本来就没有实用价值,只是老师的一个小作业,现在想知道的是有没有方法,用模板表现上面的运行时错误
yangmengxi 2008-01-03
  • 打赏
  • 举报
回复
没人回答?再自己顶一下,呵呵
yangmengxi 2008-01-02
  • 打赏
  • 举报
回复
那么如何在运行时给出错误提示呢,比如说像JAVA一样抛出一个错误并打印跟此错误有关的信息?
另外,呵呵,初来咋到,这个论坛如何编辑自己的帖子以及回复的内容啊?
yangmengxi 2008-01-02
  • 打赏
  • 举报
回复
多谢楼上的同胞,呵呵,有写错了的地方,我用的也是DEV-C++,现在改过了
//Graph.h
#include<stdio.h>
#include<iostream>
#include <string>
#include <vector>
using namespace std;
class Point;
class Arc;
class Graph{
public:
Graph(){};
vector<Point*> points;
vector<Arc*> arcs;
void addPoint(Point* s){
points.push_back(s);
cout<<"Point added"<<endl;
}
void addArc (Arc* a) {
arcs.push_back(a);
cout<<"Arc added"<<endl;
}

};
class Point{
public:
Point(){};
vector<Arc *> arcs;
};
class Arc {
public:
Arc(){};
Point * head;
Point *queue;
};

//Chimie
#import "Graph.h"
class Atom;
class Liaison;
class Molecule : virtual public Graph{
public:
Molecule(){cout<<"Molecule created"<<endl;}
};
class Atom : virtual public Point{
public:
Atom(){cout<<"Atom created"<<endl;};
};
class Liaison : virtual public Arc{
public:
Liaison(){cout<<"Liaison created"<<endl; };
};

//Reseaux.cpp
#import "Graph.h"
class Post;
class Lien;
class Reseaux : virtual public Graph{
public:
Reseaux(){cout<<"Reseaux created"<<endl;}
};
class Post : virtual public Point{
public:
Post(){cout<<"Post created"<<endl;}
};
class Lien : virtual public Arc{
public:
Lien(){cout<<"Lien created"<<endl;}
};
//Test.cpp
#import "Chimie.cpp"
#import "Reseaux.cpp"
int main(){
Molecule * m = new Molecule();
Atom *a = new Atom();
m->addPoint(a);

Graph *r = new Reseaux();
Point *p = new Post();
m->addPoint(p);// 这条代码会将电脑的实例加到分子的实例上,目的是制止这个操作(分别在编译和运行时)
getchar();

return 0;
}
yangmengxi 2008-01-02
  • 打赏
  • 举报
回复
没人回答?自己顶一下,呵呵
yangmengxi 2008-01-02
  • 打赏
  • 举报
回复
偶还有个想法,是否可以用模板的方式实现这个东西
因为老师没具体说用什么方式实现
#include<iostream>
#include <string>
#include <vector>
using namespace std;

template <typename G,typename P,typename A> class Arc{
public:
// virtual ~Arc();
};
template <typename G,typename P,typename A> class Point{
public:
// virtual ~Point();
};
template <typename G,typename P,typename A> class Graph{
public:
vector<P*> points;
vector<A*> arcs;
Graph(){cout<<"Graph created"<<endl;}
virtual void addPoint(P * p){
P *pp = (dynamic_cast<P *>(p));
if(NULL == pp){
cout<<"Error: It is not suitable!"<<endl;
}else{
points.push_back(pp);
cout<<"Point Added"<<endl;
}
}
virtual void addArc(A * a){
arcs.push_back(a);
}
virtual ~Graph(){}
};


//Chimie.cpp
#import "Graph.h"
class Atom;
class Liaison;
class Molecule;
class Atom : virtual public Point<Molecule,Atom,Liaison>{};
class Liaison : virtual public Arc<Molecule,Atom,Liaison>{};
class Molecule : virtual public Graph<Molecule,Atom,Liaison>{
public : Molecule(){cout<<"Molecule created"<<endl;}
};


//Reseaux.cpp
#import "Graph.h"

class Post;
class Lien;
class Reseaux : virtual public Graph<Reseaux,Post,Lien>{
public : Reseaux(){}
};
class Post : virtual public Point<Reseaux,Post,Lien>{
public : Post(){}
};
class Lien : virtual public Arc<Reseaux,Post,Lien>{
public : Lien(){}
};

//Test.cpp
#import "Chimie.cpp"
#import "Reseaux.cpp"

int main(){
Molecule * m = new Molecule();
Atom *a = new Atom();
Liaison *l = new Liaison();
m->addPoint(a);
Reseaux *r = new Reseaux();
Post *p = new Post();
m->addPoint(p); //这里要出现运行时的错误 getchar();
return 0;
}
也就是说派生类里不写添加点边的函数,全写在模板类里,这样有可能将错误推迟到运行时显示吗?
另外,C++的模板类里的类变量是不是不可以申明指针
如果将上面的注释去掉就有连接错误,没有虚析构函数的话不是没法dynamic_cast了吗?
请各位不吝赐教
yangmengxi 2008-01-02
  • 打赏
  • 举报
回复
多谢ltc_mouse,大致解决了!
请问这里有给分的机制吗?如何给呢?
ltc_mouse 2008-01-02
  • 打赏
  • 举报
回复
你测试过我添加的Molecule::addPoint吗?那里的dynamic_cast处理就是运行时类型检查啊,当对象不是那种类型时,得到NULL,就可以知道出错了。不过,好像没有提供Java那样的printTrace机制。C++的异常机制,我也不会,:)
ltc_mouse 2008-01-01
  • 打赏
  • 举报
回复
lz给出的代码没有编译过吧?错误好多...
感觉强制转换可以达到楼主的要求,试试这个:

class Point{
public:
Point(){}
virtual ~Point(){} //为了使用dynamic_cast,必须有虚函数
Arc * arcs[]; //我用Dev C++,不知道是不是建的工程问题,使用Arc会报错。我改名后测试的
};

class Atom : virtual public Point{ //必须在类Molecule之前定义,否则无法使用cast
public:
Atom(){cout <<"Atom created" <<endl;}
};

class Molecule : virtual public Graph{
public:
Molecule(){cout <<"Molecule created" <<endl;}
#if 0
virtual void addPoint(Atom* s){ //这种做法在编译时就会给出错误
Graph::addPoint(static_cast<Point*>(s));
}
#else
virtual void addPoint(Point *s){
Atom *atom = dynamic_cast<Atom *>(s); //向下转型,非法时得到NULL,可以给出提示
if(NULL == atom){
cout<<"Error: Invalid source!"<<endl;
}else{
Graph::addPoint(atom);
}
}
#endif
};
kevinlynx 2008-01-01
  • 打赏
  • 举报
回复
m-> addPoint(p);//
貌似本身就是错的,addPoint( Point *s ), Point和Arc没有继承关系,不明白你意思了。
csdn5211 2008-01-01
  • 打赏
  • 举报
回复
关注。

64,645

社区成员

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

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