免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 14073 | 回复: 21
打印 上一主题 下一主题

一个设计问题,this指针无法多态使用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-29 17:17 |只看该作者 |倒序浏览
Visitor Pattern

class Visitor {
public:
    int visit(D1*);
    int visit(D2*);
    void close();
};

class B {
public:
virtual void accept(Visitor* visitor)  {
    if (visitor->visit(this) == -1)
                visitor->close();
    }
};
class D1 : public B { };
class D2 : public B { };

问题:B中的this指针无法多态使用,也就是说上面的很elegant的方法行不通。必须这样:

class B {
public:
    virtual void accept(Visitor* visitor)  = 0;
};
class D1 : public B {
public:
virtual void accept(Visitor* visitor)  {
    if (visitor->visit(this) == -1)
                visitor->close();
    }
};
class D2 : public B {
public:
virtual void accept(Visitor* visitor)  {
    if (visitor->visit(this) == -1)
                visitor->close();
    }
};

也就是有丑陋的代码重复。有没有好的办法解决这个代码(算法)重用问题?template不支持虚函数,也不行。

论坛徽章:
0
2 [报告]
发表于 2009-11-29 21:50 |只看该作者
你这个本来就不是多态,要么把Visitor 类里面的visit(D1*); visit(D2*);两个函数的功能移入D1、D2类中,要么另外建一个visotorv_imp之类的类,再分别集成处理D1和处理D2的子类。

总来说,先将类的关系和类的职责设计好,不要一上来就想着多态少态,觉得别扭的时候,往往是类的职责没分配好,做了不该做的事情

论坛徽章:
0
3 [报告]
发表于 2009-11-30 00:34 |只看该作者
个人不推荐你这种写法,一 扩展性差, 二逻辑结构不是很清晰。但是可以使用template强行实现你所谓的简洁表述如下:

#include<iostream>
using namespace std;

class D1;
class D2;

class Visitor {
public:
&nbsp;&nbsp;&nbsp;&nbsp;int visit(D1*){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout << "D1" << endl;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;int visit(D2*){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout << "D2" << endl;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;void close(){ cout <<"close" << endl;}
};

template<class T>
class B {
public:
&nbsp;&nbsp;&nbsp;&nbsp;void accept(Visitor* visitor)  {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (visitor->visit(pointer_) == -1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visitor->close();
&nbsp;&nbsp;&nbsp;&nbsp;}
private:
&nbsp;&nbsp;&nbsp;&nbsp;T* pointer_;
};

class D1 : public B<D1> { };
class D2 : public B<D2> { };

int main() {
&nbsp;&nbsp;&nbsp;&nbsp;Visitor v;
&nbsp;&nbsp;&nbsp;&nbsp;D1 *a = new D1;
&nbsp;&nbsp;&nbsp;&nbsp;D2 *b = new D2;
&nbsp;&nbsp;&nbsp;&nbsp;a->accept(&v);
&nbsp;&nbsp;&nbsp;&nbsp;b->accept(&v);
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}

论坛徽章:
0
4 [报告]
发表于 2009-11-30 05:25 |只看该作者
Visitor里的visit方法应该只有一个int visit(B*)才能多态吧。。

论坛徽章:
0
5 [报告]
发表于 2009-11-30 16:03 |只看该作者
to 2,4楼朋友,请注意看帖,多态指的B体系,Visitor内函数都不是virtual我怎么会说它是多态。visitor pattern有没有用到多态建议仔细看下《设计模式》。提示:double dispatch,其一为多态,另一为重载。
谢谢3楼朋友,貌似用到递归template instanciation,但少了基类构造函数的实现,而且基类加一个成员也不好看,不见得比原来的做法好。我再仔细想想。

[ 本帖最后由 wishel 于 2009-11-30 16:09 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2009-11-30 16:20 |只看该作者
OIOIC 里的 This 指针没有这样的傻逼问题,建议LZ你去认真学习学习 OIOIC 和 WGI。

论坛徽章:
0
7 [报告]
发表于 2009-11-30 16:29 |只看该作者
楼上请文明用语,另外请不要在本贴涉及c和c++的比较问题。

论坛徽章:
9
摩羯座
日期:2013-08-15 15:18:48狮子座
日期:2013-09-12 18:07:47金牛座
日期:2013-09-16 13:23:09辰龙
日期:2013-10-09 09:03:27白羊座
日期:2013-10-17 13:32:44子鼠
日期:2014-04-23 15:09:38戌狗
日期:2014-09-17 11:37:542015年亚洲杯之韩国
日期:2015-03-26 10:16:442015亚冠之武里南联
日期:2015-08-18 14:55:52
8 [报告]
发表于 2009-11-30 16:46 |只看该作者
这个与this指针能不能使用多态半点关系没有,单这句visitor->visit(this),而this是B*类型,编译器怎么知道你是要调用D1*的,还是D2*的?父类指针不加强制转换怎么能赋给子类指针?多态根本就不是这么用的!!
或许你会想当然的认为,“我传进来的参数必定是D1或者D2的一个对象,编译器应该根据这个来决定调用哪个函数”,那么万一调用的对象是B的对象或者其他从B继承的类对象怎么半?

论坛徽章:
0
9 [报告]
发表于 2009-11-30 17:01 |只看该作者
原帖由 wishel 于 2009-11-30 16:03 发表
to 2,4楼朋友,请注意看帖,多态指的B体系,Visitor内函数都不是virtual我怎么会说它是多态。visitor pattern有没有用到多态建议仔细看下《设计模式》。提示:double dispatch,其一为多态,另一为重载。
谢谢 ...


晕倒。。。。

既然你明知Visitor内的函数不是多态,你凭什么要求调用 visitor->visit(this) 能有多态的行为?你以为使用this是个父类指针就是多态?要“this->”这样使用才是,你现在是“visitor->”这样来使用,所以关键问题在visitor上,连最基本的多态都没搞清楚,就张口《设计模式》闭口《设计模式》,现在的人啊。。。。

论坛徽章:
0
10 [报告]
发表于 2009-11-30 17:15 |只看该作者
原帖由 drangon 于 2009-11-30 17:01 发表


晕倒。。。。

既然你明知Visitor内的函数不是多态,你凭什么要求调用 visitor->visit(this) 能有多态的行为?你以为使用this是个父类指针就是多态?要“this->”这样使用才是,你现在是“visitor->”这样 ...


高人请认真看帖。请不要在本贴讨论人品问题ok?

本贴开贴就说的很清楚了,我本误以为this指针可以多态使用,结果编译器不认,this是个编译期明确的类型。
所以我想探求一种代码复用的办法。

B体系内的accept是不是多态呢?

感叹下。这年月问个问题要有很好的心理素质,要有被随处隐伏的高人怒张的板砖拍到死还说不出话的心理准备,真不容易啊。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP