Issue 3162: C++ mapping for PSDL storage object references (pss-ftf) Source: ZeroC (Mr. Bernard Normier, bernard@zeroc.com) Nature: Uncategorized Issue Severity: Summary: There is a number of problems with the C++ mapping for storage object references: * abstract storage type references are mapped to abstract C++ classes; this implies that references are dynamically allocated and freed, and typically handled through pointers. The dynamic allocation is expensive and error prone (risk of memory leaks), and handling 'smart pointers' through pointers to these smart pointers is very unusual. * The mapped C++ classes inherit from each other, to mimic the implicit widening of regular pointers. Using inheritance for this purpose is a mistake, since it does not correspond to the behavior of real pointers -- if class B derives from class A, a B instance is a A, but a B* is not a A*, it is only implictly converted into an A*. The correct way to provide this implicit widening is through conversion operators. I propose to change the mapping and adopt concrete 'smart-pointer' ref classes, that applications allocate on the stack. The proposed mapping is implemented in Orbix2000 beta 2 (available from IONA web site). Resolution: accepted Revised Text: Edit 4.4.1 to use the following mapping for references. Each reference is mapped to a concrete C++ class, which provides: - a public default constructor that creates a null reference - a non-explicit constructor which takes an incarnation of the target [abstract] storage type. - a public copy constructor - a public destructor - a public assignment operator - a public assignment operator which takes an incarnation of the target [abstract] storage type. - a public operator->() that dereferences this reference and returns the target object. The caller is not supposed to release this incarnation. - a public deref() function which behaves like operator->() - a public release() function which releases this reference - a public destroy_object() function which destroys the target object - a public get_pid() function which returns the pid of the target object. - a public get_short_pid() function which returns the short-pid of the target object. - a public is_null() function; it returns true if and only if this reference is null. - a public get_storage_home() function which returns the storage home of the target object. Actions taken: December 23, 1999: received issue October 3, 2001: closed issue Discussion: End of Annotations:===== Date: Wed, 22 Dec 1999 17:30:19 -0500 From: Bernard Normier Organization: IONA Technologies X-Mailer: Mozilla 4.61 [en] (WinNT; U) X-Accept-Language: en MIME-Version: 1.0 To: issues@omg.org Subject: PSS-FTF issue: C++ mapping for PSDL storage object references Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii X-UIDL: ;YIe99Y0!!() that dereferences this reference and returns the target object. The caller is not supposed to release this incarnation. - a public deref() function which behaves like operator->() - a public release() function which releases this reference - a public destroy_object() function which destroys the target object - a public get_pid() function which returns the pid of the target object. - a public get_short_pid() function which returns the short-pid of the target object. - a public is_null() function; it returns true if and only if this reference is null. - a public get_storage_home() function which returns the storage home of the target object. - for each direct or indirect base class of the [abstract] storage type, a convertion operator that converts this object to the corresponding ref. Each reference class also provides a typedef to its target type, _target_type. This is useful for programming with templates. For example the reference class generated for abstract storagetype A {}; is: class ARef { public: typedef A _target_type; // Constructors ARef() throw (); ARef( A* target ) throw (); ARef( const ARef& ref ) throw (); // Destructor ~ARef() throw (); // Assignment operator ARef& operator=( const ARef& ref ) throw (); ARef& operator=( T* obj ) throw (); // Conversion operators operator CosPersistentState::StorageObjectRef() const throw(); // Other member functions void release() throw (); A* operator->() throw (CORBA::SystemException); A* deref() throw (CORBA::SystemException); void destroy_object() throw (CORBA::SystemException); CosPersistentState::Pid* get_pid() const throw (CORBA::SystemException); CosPersistentState::ShortPid* get_short_pid() const throw (CORBA::SystemException); CORBA::Boolean is_null() const throw (); CosPersistentState::StorageHomeBase_ptr get_storage_home() const throw (CORBA::SystemException); // additional implementation-specific members }; With respect to memory management, a Ref behaves like a pointer (or _ptr) -- not like a var. For operation parameters, Refs are mapped as follows: PSDL C++ in ref SRef inout ref SRef& out ref SRef_out (return) ref SRef Regards, Bernard