子类调用如何判断是哪个子类?

幻夢之葉 2014-07-04 03:28:48


// A类只有接口,B,C均没有重写函数fun,知道A有运行时类信息的封装
class A
{
public:
virtual void fun(){ /*Do someting */ }
};

class B :public A{ };

class C: public A{ };

int main()
{
B *pB = new B;
C *pC = new C;

pB->fun();
pC->fun();// the result is diffrent from pB->fun();
}


有什么机制或方法知道调用的是哪个子类,如何根据不同子类分别处理?
我的想法是根据类信息判断,但是子类指针又不是作为参数如何取得类信息?
不明觉厉,还望大神指点。
...全文
772 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
幻夢之葉 2014-07-07
  • 打赏
  • 举报
回复
引用 8 楼 mujiok2003 的回复:
正确使用多态,不需判断子类型信息。一旦使用需要判断子类型信息, 一般都违反 开闭原则, liskov 替换原则, 是一个bad design
恩,以后尽量避免。不过多了解一下还是有好处的,因为很多时候是看别人代码。
幻夢之葉 2014-07-07
  • 打赏
  • 举报
回复
引用 7 楼 zcdabing 的回复:

class A
{
public:
    virtual void fun(){ /*Do someting */ }
};
 
class B :public A{ };
 
class C: public A{ };
 
int main()
{
    A *pA1 = new B;
    A *pA2= new C;
    printf("%s",typeid(*pA1).name());
    printf("%s",typeid(*pA2).name());
}
没试过不保证对 另,别纠结这些东西了,你知道dynamic_cast<&A::fun>( pA1->vptr[1])是个什么东西吗?
= = 概念上有点了解,刚才也具体去看了下。 不过因为我没有重写,所以不同子类对象虚函数指针值相同,是指向同一块地址的吧?
幻夢之葉 2014-07-07
  • 打赏
  • 举报
回复
引用 11 楼 lovesmiles 的回复:
[quote=引用 6 楼 jianwen0529 的回复:] [quote=引用 3 楼 lovesmiles 的回复:] 使用dynamic_cast强制动态转换 这个操作符对于非同种类型指针的返回值是NULL.,或者抛出异常。 所以判断一下返回值或者捕捉这个异常就可以知道这个指针是不是你要转换的类型。
这个是继承啊,完全可以转换,怎么可能返回NULL? 而且还有一个疑问,我这是想知道是具体哪个子类,跟你说的判断不同是有区别的。 就比如vector我要取size(),你却判断是否为空一样 [/quote] 你都没看懂我的意思,将b转换成c,这两个怎么就是继承关系了呢? 如果指针已经确实是子类,非b即c,将b强制转换成c肯定会有异常。 将父类转换成子类,肯定返回null。 所以如果某指针不指向c,而强行将它转换成c,转换的结果一定可以说明它是不是c。[/quote] 大概是我描述有点不准确,我是要明确知道哪个子类(不一定是2个,在实际项目中有5 6 个直接子类,执行结果是不一样的)。 我也明白你的意思,不过只能试用在两个子类之间吧?!
zilaishuichina 2014-07-04
  • 打赏
  • 举报
回复
这确实不是一个好的设计, 当然硬要实现也是能实现的

class B;
class C;

class A
{
public:
    virtual void fun();
};
 
class B :public A{ };
 
class C: public A{ };

void A::fun()
{ 
	B *pb = dynamic_cast<B*>(this);
	if (pb != NULL)
	{
		printf("class B\n");
	}
	
	C *pc = dynamic_cast<C*>(this);
	if (pc != NULL)
	{
		printf("class C\n");
	}
}

int main()
{
    B *pB = new B;
    C *pC = new C;
 
    pB->fun();
    pC->fun();// the result is diffrent from pB->fun();
}
勤奋的小游侠 2014-07-04
  • 打赏
  • 举报
回复
引用 6 楼 jianwen0529 的回复:
[quote=引用 3 楼 lovesmiles 的回复:] 使用dynamic_cast强制动态转换 这个操作符对于非同种类型指针的返回值是NULL.,或者抛出异常。 所以判断一下返回值或者捕捉这个异常就可以知道这个指针是不是你要转换的类型。
这个是继承啊,完全可以转换,怎么可能返回NULL? 而且还有一个疑问,我这是想知道是具体哪个子类,跟你说的判断不同是有区别的。 就比如vector我要取size(),你却判断是否为空一样 [/quote] 你都没看懂我的意思,将b转换成c,这两个怎么就是继承关系了呢? 如果指针已经确实是子类,非b即c,将b强制转换成c肯定会有异常。 将父类转换成子类,肯定返回null。 所以如果某指针不指向c,而强行将它转换成c,转换的结果一定可以说明它是不是c。
zcdabing 2014-07-04
  • 打赏
  • 举报
回复
引用 9 楼 mujiok2003 的回复:
[quote=引用 7 楼 zcdabing 的回复:]

class A
{
public:
    virtual void fun(){ /*Do someting */ }
};
 
class B :public A{ };
 
class C: public A{ };
 
int main()
{
    A *pA1 = new B;
    A *pA2= new C;
    printf("%s",typeid(*pA1).name());
    printf("%s",typeid(*pA2).name());
}
没试过不保证对 另,别纠结这些东西了,你知道dynamic_cast<&A::fun>( pA1->vptr[1])是个什么东西吗?
这俩东西都需要RTTI,往往 会引入更多问题,除非万不得已, 慎用。[/quote] 好的
mujiok2003 2014-07-04
  • 打赏
  • 举报
回复
引用 7 楼 zcdabing 的回复:

class A
{
public:
    virtual void fun(){ /*Do someting */ }
};
 
class B :public A{ };
 
class C: public A{ };
 
int main()
{
    A *pA1 = new B;
    A *pA2= new C;
    printf("%s",typeid(*pA1).name());
    printf("%s",typeid(*pA2).name());
}
没试过不保证对 另,别纠结这些东西了,你知道dynamic_cast<&A::fun>( pA1->vptr[1])是个什么东西吗?
这俩东西都需要RTTI,往往 会引入更多问题,除非万不得已, 慎用。
mujiok2003 2014-07-04
  • 打赏
  • 举报
回复
正确使用多态,不需判断子类型信息。一旦使用需要判断子类型信息, 一般都违反 开闭原则, liskov 替换原则, 是一个bad design
zcdabing 2014-07-04
  • 打赏
  • 举报
回复

class A
{
public:
    virtual void fun(){ /*Do someting */ }
};
 
class B :public A{ };
 
class C: public A{ };
 
int main()
{
    A *pA1 = new B;
    A *pA2= new C;
    printf("%s",typeid(*pA1).name());
    printf("%s",typeid(*pA2).name());
}
没试过不保证对 另,别纠结这些东西了,你知道dynamic_cast<&A::fun>( pA1->vptr[1])是个什么东西吗?
幻夢之葉 2014-07-04
  • 打赏
  • 举报
回复
引用 3 楼 lovesmiles 的回复:
使用dynamic_cast强制动态转换 这个操作符对于非同种类型指针的返回值是NULL.,或者抛出异常。 所以判断一下返回值或者捕捉这个异常就可以知道这个指针是不是你要转换的类型。
这个是继承啊,完全可以转换,怎么可能返回NULL? 而且还有一个疑问,我这是想知道是具体哪个子类,跟你说的判断不同是有区别的。 就比如vector我要取size(),你却判断是否为空一样
幻夢之葉 2014-07-04
  • 打赏
  • 举报
回复
引用 1 楼 bdmh 的回复:
你为什么要根据类信息区判断,那样,多态岂不是没用了,多态就干你这个事的,具体事情交给创建的子类去实现不同的内容
这个只是举例,真实的代码重写的函数有很多,但是不包括这个。
幻夢之葉 2014-07-04
  • 打赏
  • 举报
回复
引用 1 楼 bdmh 的回复:
你为什么要根据类信息区判断,那样,多态岂不是没用了,多态就干你这个事的,具体事情交给创建的子类去实现不同的内容
我只是用接口 = = ,它确实是这样子实现了,那部分代码没有。 现在就不考虑他为什么这么实现了,我就是想知道怎么实现哈。
勤奋的小游侠 2014-07-04
  • 打赏
  • 举报
回复
使用dynamic_cast强制动态转换 这个操作符对于非同种类型指针的返回值是NULL.,或者抛出异常。 所以判断一下返回值或者捕捉这个异常就可以知道这个指针是不是你要转换的类型。
layershow 2014-07-04
  • 打赏
  • 举报
回复
B,C均没有重写函数fun ,偷懒……
bdmh 2014-07-04
  • 打赏
  • 举报
回复
你为什么要根据类信息区判断,那样,多态岂不是没用了,多态就干你这个事的,具体事情交给创建的子类去实现不同的内容

64,654

社区成员

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

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