What does this code do?
-
Sorry for the duplicate post but the first one stripped off the template args. Look near the bottom of the code snippet. I'm not sure what the code is doing, can someone explain.
template<typename _IIID> class _com_ptr_t {
public:
typedef _IIID ThisIIID;
typedef typename _IIID::Interface Interface;
static const IID& GetIID() throw()
{
return ThisIIID::GetIID();
}template<typename \_OtherIID> \_com\_ptr\_t(const \_com\_ptr\_t<\_OtherIID>& p) throw(\_com\_error) : m\_pInterface(NULL) { HRESULT hr = \_QueryInterface(p); if (FAILED(hr) && (hr != E\_NOINTERFACE)) { \_com\_issue\_error(hr); } } template<typename \_InterfaceType> \_com\_ptr\_t(\_InterfaceType\* p) throw(\_com\_error) : m\_pInterface(NULL) { HRESULT hr = \_QueryInterface(p); if (FAILED(hr) && (hr != E\_NOINTERFACE)) { \_com\_issue\_error(hr); } } template<> \_com\_ptr\_t(LPSTR str) throw(\_com\_error) { new(this) \_com\_ptr\_t(static\_cast (str), NULL); } ...
}
-
Sorry for the duplicate post but the first one stripped off the template args. Look near the bottom of the code snippet. I'm not sure what the code is doing, can someone explain.
template<typename _IIID> class _com_ptr_t {
public:
typedef _IIID ThisIIID;
typedef typename _IIID::Interface Interface;
static const IID& GetIID() throw()
{
return ThisIIID::GetIID();
}template<typename \_OtherIID> \_com\_ptr\_t(const \_com\_ptr\_t<\_OtherIID>& p) throw(\_com\_error) : m\_pInterface(NULL) { HRESULT hr = \_QueryInterface(p); if (FAILED(hr) && (hr != E\_NOINTERFACE)) { \_com\_issue\_error(hr); } } template<typename \_InterfaceType> \_com\_ptr\_t(\_InterfaceType\* p) throw(\_com\_error) : m\_pInterface(NULL) { HRESULT hr = \_QueryInterface(p); if (FAILED(hr) && (hr != E\_NOINTERFACE)) { \_com\_issue\_error(hr); } } template<> \_com\_ptr\_t(LPSTR str) throw(\_com\_error) { new(this) \_com\_ptr\_t(static\_cast (str), NULL); } ...
}
Gerald Schwab wrote: template<> _com_ptr_t(LPSTR str) throw(_com_error) { new(this) _com_ptr_t(static_cast<LPCSTR>(str), NULL); } That is calling one constructor from another. Since the constructor that takes an LPCSTR is marked
explicit
, a different constructor was needed that takes an LPSTR. (explicit
means that the constructor parameter must exactly match LPCSTR, no implicit conversions (such as adding a const qualification to convert an LPSTR to an LPCSTR) are allowed.) This totally negates the purpose of having theexplicit
constructor, but oh well. Thenew(this)
calls anoperator new
defined in new.h, which is #include'd at the top of comip.h. --Mike-- "Jobs that don't allow you to visit the Lounge 25 times a day at the minimum are not worth having anyway." -- Nish, 3/28/2002 My really out-of-date homepage Sonork - 100.10414 AcidHelm Big fan of Alyson Hannigan and Jamie Salé. -
Gerald Schwab wrote: template<> _com_ptr_t(LPSTR str) throw(_com_error) { new(this) _com_ptr_t(static_cast<LPCSTR>(str), NULL); } That is calling one constructor from another. Since the constructor that takes an LPCSTR is marked
explicit
, a different constructor was needed that takes an LPSTR. (explicit
means that the constructor parameter must exactly match LPCSTR, no implicit conversions (such as adding a const qualification to convert an LPSTR to an LPCSTR) are allowed.) This totally negates the purpose of having theexplicit
constructor, but oh well. Thenew(this)
calls anoperator new
defined in new.h, which is #include'd at the top of comip.h. --Mike-- "Jobs that don't allow you to visit the Lounge 25 times a day at the minimum are not worth having anyway." -- Nish, 3/28/2002 My really out-of-date homepage Sonork - 100.10414 AcidHelm Big fan of Alyson Hannigan and Jamie Salé.Thanks for the reply Michael. I understand the "explicit" part, but I'm still a little fuzzy on the "new" part. I stepped through the code with the debugger and it looks like this constuctor is instantiating itself using the explicit constructor. Here's what I don't quit get: when "new(this)" is called, "this" already has an address. So is this constructor calling the explicit constructor and replacing itself with the constructed value of the explicit contructor? Or is it casting from this constructor to the explicit constructor? I understand the result, I just don't quite grasp how the code gets there.
-
Gerald Schwab wrote: template<> _com_ptr_t(LPSTR str) throw(_com_error) { new(this) _com_ptr_t(static_cast<LPCSTR>(str), NULL); } That is calling one constructor from another. Since the constructor that takes an LPCSTR is marked
explicit
, a different constructor was needed that takes an LPSTR. (explicit
means that the constructor parameter must exactly match LPCSTR, no implicit conversions (such as adding a const qualification to convert an LPSTR to an LPCSTR) are allowed.) This totally negates the purpose of having theexplicit
constructor, but oh well. Thenew(this)
calls anoperator new
defined in new.h, which is #include'd at the top of comip.h. --Mike-- "Jobs that don't allow you to visit the Lounge 25 times a day at the minimum are not worth having anyway." -- Nish, 3/28/2002 My really out-of-date homepage Sonork - 100.10414 AcidHelm Big fan of Alyson Hannigan and Jamie Salé.Mike, I see you continue to include a link to your "really out-of-date homepage" when are you going to update it? Nick Parker
-
Thanks for the reply Michael. I understand the "explicit" part, but I'm still a little fuzzy on the "new" part. I stepped through the code with the debugger and it looks like this constuctor is instantiating itself using the explicit constructor. Here's what I don't quit get: when "new(this)" is called, "this" already has an address. So is this constructor calling the explicit constructor and replacing itself with the constructed value of the explicit contructor? Or is it casting from this constructor to the explicit constructor? I understand the result, I just don't quite grasp how the code gets there.
The purpose of new() is usually to allocate memory and return a pointer to it, however you can overload new() to do anything. That's what that constructor does, it calls an overloaded new() that just returns the parameter passed to it. Since there is already memory allocated for
this
, new() returns that address, then C++ calls the constructor. It is bloody confusing, though. ;) --Mike-- "Jobs that don't allow you to visit the Lounge 25 times a day at the minimum are not worth having anyway." -- Nish, 3/28/2002 My really out-of-date homepage Sonork - 100.10414 AcidHelm Big fan of Alyson Hannigan and Jamie Salé. -
Mike, I see you continue to include a link to your "really out-of-date homepage" when are you going to update it? Nick Parker
I know, I know. *hangs head in shame* ;) --Mike-- "Jobs that don't allow you to visit the Lounge 25 times a day at the minimum are not worth having anyway." -- Nish, 3/28/2002 My really out-of-date homepage Sonork - 100.10414 AcidHelm Big fan of Alyson Hannigan and Jamie Salé.