[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