返回   cpper编程论坛 > C/CPP/TMP/GP
注册账号 论坛帮助 会员列表 日历事件 搜索 今日新帖 标记版面已读

回复
 
LinkBack 主题工具 显示模式
  #1 (permalink)  
旧 2008-01-01
初级会员
 
注册日期: 2008-01-01
帖子: 3
qiangmu 正向着好的方向发展
默认 请教各位学长一个东西,意思简单,但实现有点问题

有三个类 图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(){}; 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; }
现在目的是要禁止红色这条语句的发生,如何做?
老师的要求是让程序
1.编译时报错
2.运行时报错,并且报错时安全显示

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

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

小弟刚开始C++,诚意请各位老鸟指点一二。

此帖于 2008-01-02 01:13 AM 被 qiangmu 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #2 (permalink)  
旧 2008-01-03
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,135
文章: 20
polyrandom 正向着好的方向发展
默认 回复: 请教各位学长一个东西,意思简单,但实现有点问题

你的Graph体系其实是一个概念上的抽象,不同的Graph体系之间是没有联系的。也就是说,网络和分子虽然是同构的,但是它们之间没有任何互操作性。
这样的话,其实你可以把Graph体系做成一个(套)模板:
代码:
template<typename Arc, typename Point> class Graph {...} typedef Graph<Liaison, Atom> Molecule;
在这种情况下,编译时就会出错。
如果要运行时出错的话非常简单,随便加个virtual函数就可以搞定。要像Java那样的话,也可以用RTTI。不过我还是喜欢上面的方法。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #3 (permalink)  
旧 2008-01-03
初级会员
 
注册日期: 2008-01-01
帖子: 3
qiangmu 正向着好的方向发展
默认 回复: 请教各位学长一个东西,意思简单,但实现有点问题

对不起,楼上的可以解释清楚一些吗?用模板是个,跟我想法一样,非常棒的思路!!
我还不太明白,用typedef的话,跟virtual有什么关系?有virtual的话又如何得出运行时错误?我写成如下这样可以吗?
不胜感激
//Graph.h
#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了吗?

此帖于 2008-01-03 08:13 PM 被 qiangmu 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #4 (permalink)  
旧 2008-01-04
论坛管理员
 
注册日期: 2006-02-09
帖子: 99
文章: 1
cpper 的声望功能已被禁用
默认 回复: 请教各位学长一个东西,意思简单,但实现有点问题

代码:
#include <vector> template<typename Point, typename Arc> class Graph { typedef std::vector<Point> Points; typedef std::vector<Arc> Arcs; Points points_; Arcs arcs_; public: void addPoint( const Point& p ) { points_.push_back( p ); } void addArc( const Arc& a ) { arcs_.push_back( a ); } }; class Atom {}; class Liaison {}; typedef Graph<Atom, Liaison> Molecule; class Post {}; class Lien {}; class Reseaux : public Graph<Post, Lien> {}; int wmain() { Molecule m; m.addPoint( Atom() ); m.addArc( Liaison() ); Reseaux r; r.addPoint( Post() ); r.addArc( Lien() ); // r.addPoint( Atom() ); compile error return 0; }
btw: dynamic_cast的前提是虚函数,而不是虚析构函数,虽然有虚函数最好有虚析构函数。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #5 (permalink)  
旧 2008-01-04
初级会员
 
注册日期: 2008-01-01
帖子: 3
qiangmu 正向着好的方向发展
默认 回复: 请教各位学长一个东西,意思简单,但实现有点问题

多谢楼上的热心提点,我的意思是想要的是运行时错误并提示类似“This is not a Post”之类的信息,不是编译时的错误,这样用模板如何写呢?请指教

此帖于 2008-01-05 12:17 AM 被 qiangmu 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛禁用 HTML 代码
Trackbacks are 启用
Pingbacks are 启用
Refbacks are 启用



所有时间均为格林尼治时间 +9。现在的时间是 08:54 AM


Powered by vBulletin® 版本 3.7.0
版权所有 ©2000 - 2008,Jelsoft Enterprises Ltd.
(C) Copy Right All Right Reserved 2001 - 2007

Search Engine Friendly URLs by vBSEO 3.1.0