|
Boost Users : |
From: Jean-François Brouillet (verec_at_[hidden])
Date: 2005-05-07 21:12:23
- I'm porting to C++ a huge java library.
- Java constructor semantics is close to that of C++ but not identical.
- boost::shared_ptr does nearly exactly what I want except for
1 little thing peculiar to the project I'm working on.
The short story is that, for the C++ version, I need an "after ctor"
method to be called before any other member function is allowed
to be called. The logical next step was to override operator->
which led me to a long route ending now with boost::shared_ptr.
I should be able to solve my problem by _patching_ my local copy of
shared_ptr.hpp
as follows:
...
template<class Y>
explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y
must be complete
{
p->constructor() ; // single patch for my purpose
detail::sp_enable_shared_from_this( pn, p, p );
}
...
But obviously, I'd rather not do that. So I came up with:
template <typename T>
struct Bridge : public boost::shared_ptr<T> {
template <typename Y>
explicit Bridge(Y * y) : boost::shared_ptr<Y>(y) {
if (y) {
y->constructor() ;
}
}
} ;
But then, the guarantee given in the boost shared_ptr documenation
was broken:
Quote: shared_ptr<T> can be implicitly converted to shared_ptr<U>
whenever T* can be implicitly converted to U*. In
particular,
shared_ptr<T> is implicitly convertible to shared_ptr<T
const>,
to shared_ptr<U> where U is an accessible base of T, and to
shared_ptr<void>.
So, I added a copy constructor:
template <typename T>
struct Bridge : public boost::shared_ptr<T> {
template <typename Y>
explicit Bridge(Y * y) : boost::shared_ptr<Y>(y) {
if (y) {
y->javaConstructor() ;
}
}
template<typename Y>
Bridge(Bridge<Y> const & r) : boost::shared_ptr<Y>(r) {
}
} ;
But then I get:
/Users/verec/Tools/boost_1_32_0/osx/main.cpp: In constructor
`Bridge<T>::Bridge(const Bridge<Y>&) [with Y = DisplayStruct, T =
DeviceStruct]':
/Users/verec/Tools/boost_1_32_0/osx/main.cpp:243: instantiated from
here
/Users/verec/Tools/boost_1_32_0/osx/main.cpp:21: error: type 'class
boost::shared_ptr<DisplayStruct>' is not a direct base of
'Bridge<DeviceStruct>'
Here's the relevant part of the code:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <boost/shared_ptr.hpp>
struct ObjectStruct {
ObjectStruct() { } ;
virtual void constructor() { }
virtual ~ObjectStruct() { }
} ;
typedef Bridge<ObjectStruct> Object ;
struct DeviceStruct : public ObjectStruct {
typedef Bridge<DeviceStruct> Device ;
DeviceStruct() { std::cout << "Device
standard c++ constructor." << std::endl ; }
virtual void deviceMethod() { std::cout <<
"DeviceStruct::deviceMethod." << std::endl ; }
virtual void constructor() { std::cout << "java's
Device::constructor." << std::endl ; }
static Device current ;
static Device getCurrent() { return current ; }
} ;
typedef Bridge<DeviceStruct> Device ;
struct DisplayStruct : public DeviceStruct {
typedef Bridge<DisplayStruct> Display ;
DisplayStruct() {
std::cout << "Display standard c++ constructor." << std::endl ;
}
DisplayStruct() { std::cout << "Display
standard c++ constructor." << std::endl ; }
virtual void constructor() { DeviceStruct::constructor
() ; std::cout << "java's Display::constructor." << std::endl ; }
virtual void deviceMethod() { DeviceStruct::deviceMethod
() ; std::cout << "DisplayStruct::deviceMethod." << std::endl ; }
virtual void displayMethod() { std::cout <<
"displayMethod." << std::endl ; }
} ;
typedef Bridge<DisplayStruct> Display ;
void
callDevice(Device d) {
d->deviceMethod() ;
}
int main (int argc, char * const argv[]) {
Display display(new Display) ;
Device device(new DeviceStruct) ;
callDevice(device) ;
callDevice(display) ;
return 0 ;
}
What am I missing ?
Many Thanks.
-- Jean-François Brouillet verec_at_[hidden]
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net