[C++-sig] Re: Problems with dynamic casts
Aaron Bentley
abentley at panoramicfeedback.com
Wed Mar 16 22:13:03 CET 2005
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