[C++-sig] Re: Problems with dynamic casts

Aaron Bentley abentley at panoramicfeedback.com
Fri Mar 18 17:03:28 CET 2005


Does anyone have any suggestions for dealing with these issues?

Aaron

Aaron Bentley wrote:
> David Abrahams wrote:
> 
>> Aaron Bentley <abentley at panoramicfeedback.com> writes:
>>
>>
>>> Hi,
>>> I'm having a problem with dynamic casting on an object constructed 
>>> using Python.  It seems as though the type of an owned object is 
>>> being lost.
> 
> 
>> I suggest you reduce your problem to the smallest possible example
>> that illustrates it.  The answer will probably become obvious to you,
>> but if it doesn't, please post your example here.
> 
> 
> Okay, here's some stripped down examples:
> 
> ---foo.h---
> class BaseClass
> {
>     public:
>     BaseClass()
>     {}
>     virtual ~BaseClass()
>     {}
> };
> 
> ---foo.cpp---
> ...
> SubClass *subclass_cast(BaseClass *el)
> {
>     return dynamic_cast<SubClass *>(el);
> }
> ---bar.h---
> class SubClass: public BaseClass
> {
>     public:
>     SubClass();
> };
> SubClass *subclass_cast(BaseClass *el);
> 
> void test_subclass(SubClass &el);
> ---bar.cpp---
> ...
> SubClass::SubClass()
> {
> }
> void test_subclass(SubClass &el)
> {
>     ;
> }
> --wrapper.cpp--
> ...
> BaseClass *return_base(SubClass *el)
> {
>     return el;
> }
> ...
> BOOST_PYTHON_MODULE(_element)
> {
>     class_<BaseClass, std::auto_ptr<BaseClass>, boost::noncopyable>(
>         "BaseClass", no_init)
>         ;
>     class_<SubClass, std::auto_ptr<SubClass>, bases<BaseClass>,
>           boost::noncopyable>("SubClass")
>       ;
>     def ("subclass_cast", subclass_cast, return_internal_reference<1>());
>     def ("test_subclass", test_subclass);
>     def ("return_base", return_base, return_internal_reference<1>());
> 
> ...
> }
> --- test.py ---
> import _element
> def run_test(test_func, converter, caster, subclass):
>     print "Testing %s" % subclass.__name__
>     subcl = subclass()
>     try:
>         test_func(subcl)
>         print "subcl can be passed to %s directly" % test_func.__name__
>     except Exception, e:
>         print
>         print e
>         print "subcl cannot be passed to %s directly:" % test_func.__name__
>     try:
>         test_func(converter(subcl))
>         print "subcl can be passed to %s when returned as a base class" % \
>             test_func.__name__
>     except Exception, e:
>         print
>         print e
>         print "subcl cannot be passed to %s when returned as a base 
> class" % \
>             test_func.__name__
>     try:
>         assert caster((subcl)) is not None
>         print "subcl can be dynamically cast from subclass"
>     except Exception, e:
>         print
>         if len(str(e)) > 0:
>             print e
>         print e.__class__
>         print "subcl cannot be dynamically cast from subclass"
>     try:
>         assert caster(converter(subcl)) is not None
>         print "subcl can be dynamically cast from base class"
>     except Exception, e:
>         print
>         if len(str(e)) > 0:
>             print e
>         print e.__class__
>         print "subcl cannot be dynamically cast from base class"
> run_test(_element.test_subclass, _element.return_base, 
> _element.subclass_cast, _element.SubClass)
> 
> 
> Everything except wrapper.cpp is built as one shared library.
> 
> When I run test.py, I get this:
> Testing SubClass
> subcl can be passed to test_subclass directly
> 
> Python argument types in
>     pflib._element.test_subclass(SubClass)
> did not match C++ signature:
>     test_subclass(8SubClass {lvalue})
> subcl cannot be passed to test_subclass when returned as a base class
> subcl can be dynamically cast from subclass
> subcl can be dynamically cast from base class
> 
> If I change the constructor for SubClass to an inline constructor, I get 
> this:
> Testing SubClass
> subcl can be passed to test_subclass directly
> subcl can be passed to test_subclass when returned as a base class
> 
> exceptions.AssertionError
> subcl cannot be dynamically cast from subclass
> 
> exceptions.AssertionError
> subcl cannot be dynamically cast from base class
> 
> So it seems I can't do implicit dynamic casts (passing a base-class 
> pointer to a function taking a subclass pointer) and explicit dynamic 
> casts at the same time.
> 
> Aaron
> 


-- 
Aaron Bentley
Director of Technology
Panometrics, Inc.




More information about the Cplusplus-sig mailing list