internally cstring::allocsysstring() allocates a new bstr using the apis we examined in an earlier paragraph and copies its contents to the newly created system string, which is eventually returned to the caller. there is no such function as cstring::freesysstring(), so to deallocate the memory occupied by the returned bstr, the global api ::sysfreestring() will have to be called. cstring::setsysstring() instead reallocates the bstr pointed to by the parameter and copies its contents into it. both methods throw cmemoryexception exception objects in case of memory allocation problems.
moreover, if you are using visual c++ 5.0 or higher, you can exploit the direct to com proprietary extension which includes, among many other things, a _bstr_t class. the documentation reports that it is defined inside comdef.h, while in reality its declaration resides in comutil.h. the degree of encapsulation and functionality is similar to atl's ccombstr, but remember that using the com compiler support binds you to visual c++ even more than atl would do. probably the most relevant difference between the two implementations is that _bstr_t raises c++ exceptions and thus requires your code to be prepared to catch them, whereas ccombstr does not. this detail will likely influence your choice more than all the other possible considerations. the following code listing summarizes the public interface of _bstr_t; the comments should make it easy to understand what the diverse method groups are up to:
class _bstr_t {public: // constructors // _bstr_t() throw(); _bstr_t(const _bstr_t& s) throw(); _bstr_t(const char* s) throw(_com_error); _bstr_t(const wchar_t* s) throw(_com_error); _bstr_t(const _variant_t& var) throw(_com_error); _bstr_t(bstr bstr, bool fcopy) throw(_com_error); // destructor // ~_bstr_t() throw(); // assignment operators // _bstr_t& operator=(const _bstr_t& s) throw(); _bstr_t& operator=(const char* s) throw(_com_error); _bstr_t& operator=(const wchar_t* s) throw(_com_error); _bstr_t& operator=(const _variant_t& var) throw(_com_error); // operators // _bstr_t& operator+=(const _bstr_t& s) throw(_com_error); _bstr_t operator+(const _bstr_t& s) const throw(_com_error); // friend operators // friend _bstr_t operator+(const char* s1, const _bstr_t& s2); friend _bstr_t operator+(const wchar_t* s1, const _bstr_t& s2); // extractors // operator const wchar_t*() const throw(); operator wchar_t*() const throw(); operator const char*() const throw(_com_error); operator char*() const throw(_com_error); // comparison operators // bool operator!() const throw(); bool operator==(const _bstr_t& str) const throw(); bool operator!=(const _bstr_t& str) const throw(); bool operator<(const _bstr_t& str) const throw(); bool operator>(const _bstr_t& str) const throw(); bool operator<=(const _bstr_t& str) const throw();bool |