模板&多态类 [英] templates & polymorphic classes

查看:69
本文介绍了模板&多态类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在设计特定版本的auto_ptr

时遇到的一个问题是,我必须在多态和多态之间进行区分。参数和平原一个,

因为模板必须在内部转换为void *。


具体来说,

模板< typename T> ; void f(T * t){

void * p = dynamic_cast< void *>(t);

}

$ b $如果T不是一个至少具有某个虚拟函数的类,那么b将无法编译。特别是,没有一个STL容器可以为T确定



然而,由于多重继承,如果我想要到达基数

大多数 class,dynamic_cast< void *>是要走的路。


我可以使用reinterpret_cast,这对所有的T,

都有效,除非我失去了施放到基地上面提到的功能。


我也可以使用一对模板,一个用于多态类型,

和一个POD。但我宁愿不这样做。


我会对运行时查询感到满意......如果我可以设计一个,那就是。


typeid()似乎不适用于这种情况。


理想情况下,如果我能想出


模板< typename T>

bool is_polymorphic(T t){

...

}


我会满心欢喜:-)


任何接受者?

-

JFB

解决方案

verec写道:

我在设计特定版本时遇到了一个问题auto_ptr
是我必须在多态和多态之间进行区分。参数和普通
一些,因为模板必须在内部转换为void *。

具体来说,
模板< typename T> void f(T * t){
void * p = dynamic_cast< void *>(t);
}
如果T不是,则无法编译至少具有虚拟功能的类。


它不会工作,因为dynamic_cast只能在一个类

层次结构中运行,而''void''不属于它。它对我来说似乎没有多大的意义。如何以及为什么你想要一个动态广播来判断某个对象是否来自''void'?为什么不只是

static_cast?

特别是,没有一个STL容器确实符合T.

然而,因为多重继承,如果我想要到达基地最的话。 class,dynamic_cast< void *>是要走的路。


编号''void''不是基类。

我可以使用reinterpret_cast代替,这对所有T都适用,除了我失去了施放到基地之外上面提到的功能。


我没有看到你需要的东西。

我也可以使用一对模板,一个用于多态类型,一个和一个POD。但我宁愿不这样做。

我会对运行时查询感到满意......如果我可以设计一个,那就是。


为什么?

typeid()似乎不适用于这种情况。

理想情况下,如果我能上来用

模板< typename T>
bool is_polymorphic(T t){
...
}
我会被填满很高兴:-)

任何接受者?




2005-06-16 00:26:40 + 0100,Rolf Magnus< ra ****** @ t-online.de>说:

如果T不是一个至少具有虚拟功能的类,则不会编译。


它不会工作,因为dynamic_cast只能在一个类层次结构中工作,而''void''不属于它。对我来说似乎也没什么意义。你想要一个动态广播如何以及为什么要尝试检查一个对象是否来自''void'?为什么不只是
static_cast?




对不起,我并没有让自己清楚。一个实际的例子

可能会有所帮助。考虑:


模板< typename T> struct my_ptr {

void * rawValue;

my_ptr(T * t):rawValue(dynamic_cast< void *>(t)){

}

};


struct polymorphic {

virtual~polyorphicic();

} ;


struct pod {

};


typedef my_ptr< polymorphic> Poly;

typedef my_ptr< pod> Pod;


void

test_00005(){

Poly p(new polymorphic);

// Pod pp(新pod);

}


如果我离开Pod pp行注释掉,一切都编译和工作

罚款。但是,如果我取消注释它,我会得到:

### error:不能dynamic_cast''t''(类型''struct pod *'')键入''void *''

###(源类型不是多态的)


我所追求的是一种在上面定义''my_ptr'以便它处理的方法br />
正确使用多态和POD结构。在多态的情况下需要

dynamic_cast。结构是因为当使用

MI时,dynamic_cast保证你得到一个指针返回基础对象的
,无论派生的是什么分支

用于T.


如果还有什么不清楚,请告诉我。


我想要的只是一个写一次,随处运行 (TM :-)模板,我可以在所有地方使用,而不必先询问,我是否使用吊舱或聚合物交易

? ;


非常感谢。

-

JFB


-

帮助您的用户:给他们风格: http://www.uiwithstyle .org


verec写道:

2005-06-16 00:26:40 +0100, Rolf Magnus< ra ****** @ t-online.de>说:

如果T不是一个至少具有虚拟功能的类,则不会编译。

它永远不会工作,因为dynamic_cast只能在一个类层次结构中工作,而''void''不属于它。对我来说似乎也没什么意义。你想要一个动态广播如何以及为什么要尝试检查一个对象是否来自''void'?为什么不只是
static_cast?



对不起,我没有让自己清楚。一个实际的例子可能会有所帮助。考虑:

模板< typename T> struct my_ptr {
void * rawValue;
my_ptr(T * t):rawValue(dynamic_cast< void *>(t)){




无需使用''dynamic_cast''将指针转换为对象

为void *。它是可转换_Implicitly_。

}
};

struct polymorphic {
virtual~polyorphicic();
};

struct pod {
};

typedef my_ptr< polymorphic> Poly;
typedef my_ptr< pod> Pod;

void
test_00005(){
Poly p(new polymorphic);
// Pod pp(新pod);
}

如果我离开Pod pp一行注释,一切编译和工作
罚款。但是,如果我取消注释它,我会得到:

### error:不能dynamic_cast''t''(类型''struct pod *'')键入''void *''
###(源类型不是多态的)

我所追求的是一种在上面定义''my_ptr'的方法,以便它正确处理多态和POD结构。在多态的情况下需要
dynamic_cast。结构是因为当使用MI时,dynamic_cast保证你得到一个指针返回基础对象,无论派生的哪个分支被用于T.


基础对象是什么?你存储的指针是''void *''!

如果还有什么不清楚的地方,请告诉我。


天哪,是的。也许你可以发布_real_''my_ptr''类。

我想要的只是写一次,随处运行。 (TM :-)模板,我可以在任何地方使用,而不必先询问,我是否用吊舱或聚合物处理



您还应该尝试显示_how_您将使用类型为

''my_ptr''的对象。 我可以在所有地方使用是一个过于模糊的陈述,是任何价值的b $ b。


V


One problem I''ve come accross in designing a specific version of auto_ptr
is that I have to disntiguish between "polymorphic" arguments and "plain" ones,
because the template has to, internally, cast to void *.

Specifically,
template <typename T> void f(T * t) {
void * p = dynamic_cast<void *>(t) ;
}

will not compile if T isn''t of a class that has somewhere at least
a virtual function. In particular, none of the STL containers do qualify
for T.

Yet, because of multiple inheritance, if I want to get down to the base
"most" class, the dynamic_cast<void*> is the way to go.

I could use reinterpret_cast instead, and this would work for all T,
except that I''d lose the "cast to base" feature mentionned above.

I could also use a pair of templates, one for polymorphic types,
and one of "POD". But I''d rather not do that.

I''d be happy with a runtime query ... if I could devise one, that is.

typeid() seems to not be applicable in this context.

Ideally, if I could come up with

template <typename T>
bool is_polymorphic(T t) {
...
}

I would be filled with joy :-)

Any taker?
--
JFB

解决方案

verec wrote:

One problem I''ve come accross in designing a specific version of auto_ptr
is that I have to disntiguish between "polymorphic" arguments and "plain"
ones, because the template has to, internally, cast to void *.

Specifically,
template <typename T> void f(T * t) {
void * p = dynamic_cast<void *>(t) ;
}

will not compile if T isn''t of a class that has somewhere at least
a virtual function.
It won''t ever work, because dynamic_cast only works within a class
hierarchy, and ''void'' doesn''t belong to it. It doesn''t seem to make much
sense to me either. How and why would you want a dynamic_cast that would
attempt to check whether an object is derived from ''void''? Why not just
static_cast?
In particular, none of the STL containers do qualify
for T.

Yet, because of multiple inheritance, if I want to get down to the base
"most" class, the dynamic_cast<void*> is the way to go.
No. ''void'' is not the base class.
I could use reinterpret_cast instead, and this would work for all T,
except that I''d lose the "cast to base" feature mentionned above.
I fail to see what you need that for.
I could also use a pair of templates, one for polymorphic types,
and one of "POD". But I''d rather not do that.

I''d be happy with a runtime query ... if I could devise one, that is.
What for?
typeid() seems to not be applicable in this context.

Ideally, if I could come up with

template <typename T>
bool is_polymorphic(T t) {
...
}

I would be filled with joy :-)

Any taker?




On 2005-06-16 00:26:40 +0100, Rolf Magnus <ra******@t-online.de> said:

will not compile if T isn''t of a class that has somewhere at least
a virtual function.



It won''t ever work, because dynamic_cast only works within a class
hierarchy, and ''void'' doesn''t belong to it. It doesn''t seem to make much
sense to me either. How and why would you want a dynamic_cast that would
attempt to check whether an object is derived from ''void''? Why not just
static_cast?



I''m sorry I didn''t make myself clear enough. An actual example will
probably help. Consider:

template <typename T> struct my_ptr {
void * rawValue ;
my_ptr(T *t) : rawValue(dynamic_cast<void *>(t)) {
}
} ;

struct polymorphic {
virtual ~polymorphic() ;
} ;

struct pod {
} ;

typedef my_ptr<polymorphic> Poly ;
typedef my_ptr<pod> Pod ;

void
test_00005() {
Poly p(new polymorphic) ;
// Pod pp(new pod) ;
}

If I leave the "Pod pp" line commented out, everything compiles and works
fine. However, if I uncomment it, I get:
### error: cannot dynamic_cast ''t'' (of type ''struct pod*'') to type ''void*''
### (source type is not polymorphic)

What I am after, is a way to define ''my_ptr'' above so that it deals
correctly with both polymorphic and POD structs. The need for the
dynamic_cast in the case of "polymorphic" structs is because when
MI is used, dynamic_cast guarantees that you get a pointer back to
the base object, no matter what branch of the derivation has been
used for T.

If anything is still unclear, please, let me know.

All I want is a "write once, run anywhere" (TM :-) template that I
can use all over the place, without having to ask first, "Am I dealing
with a pod or a poly?"

Many Thanks.
--
JFB

--
Do your users a favor: give them Style: http://www.uiwithstyle.org


verec wrote:

On 2005-06-16 00:26:40 +0100, Rolf Magnus <ra******@t-online.de> said:

will not compile if T isn''t of a class that has somewhere at least
a virtual function.

It won''t ever work, because dynamic_cast only works within a class
hierarchy, and ''void'' doesn''t belong to it. It doesn''t seem to make much
sense to me either. How and why would you want a dynamic_cast that would
attempt to check whether an object is derived from ''void''? Why not just
static_cast?


I''m sorry I didn''t make myself clear enough. An actual example will
probably help. Consider:

template <typename T> struct my_ptr {
void * rawValue ;
my_ptr(T *t) : rawValue(dynamic_cast<void *>(t)) {



There is no need to use ''dynamic_cast'' to convert a pointer to an object
to void*. It''s convertible _implicitly_.
}
} ;

struct polymorphic {
virtual ~polymorphic() ;
} ;

struct pod {
} ;

typedef my_ptr<polymorphic> Poly ;
typedef my_ptr<pod> Pod ;

void
test_00005() {
Poly p(new polymorphic) ;
// Pod pp(new pod) ;
}

If I leave the "Pod pp" line commented out, everything compiles and works
fine. However, if I uncomment it, I get:
### error: cannot dynamic_cast ''t'' (of type ''struct pod*'') to type ''void*''
### (source type is not polymorphic)

What I am after, is a way to define ''my_ptr'' above so that it deals
correctly with both polymorphic and POD structs. The need for the
dynamic_cast in the case of "polymorphic" structs is because when
MI is used, dynamic_cast guarantees that you get a pointer back to
the base object, no matter what branch of the derivation has been
used for T.
To what base object? The pointer you store is ''void*''!
If anything is still unclear, please, let me know.
Hell, yes. Perhaps you could post the _real_ ''my_ptr'' class.
All I want is a "write once, run anywhere" (TM :-) template that I
can use all over the place, without having to ask first, "Am I dealing
with a pod or a poly?"



You should also try to show _how_ you''re going to use an object of type
''my_ptr''. "I can use all over the place" is too vague a statement to be
of any value.

V


这篇关于模板&amp;多态类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆