Initializing a class pointer
Steven Schveighoffer
schveiguy at yahoo.com
Sun Feb 27 05:39:33 PST 2011
On Sat, 26 Feb 2011 19:46:18 -0500, Tyro[a.c.edwards] <nospam at home.com>
wrote:
> On 2/27/2011 8:52 AM, Simen kjaeraas wrote:
>> Tyro[a.c.edwards] <nospam at home.com> wrote:
>>
>>> I'm trying to convert some c++ code that defines
>>>
>>> T func(par...)
>>> {
>>> Controller * pCtrl = WinGetLong<Controller *> (hwnd);
>>> .
>>> .
>>> .
>>> switch(msg)
>>> {
>>> case FirstMatch:
>>> pCtrl = new Controller (hwnd, reinterpret_cast<CREATESTRUCT *>
>>> (lParam));
>>> break;
>>> }
>>> }
>>>
>>> I'm not sure why I need a pointer to the class, just trying to figure
>>> it out.
>>
>> Ah. You would not need a pointer to the class in D. Instead, your
>> function
>> would look something like this:
>>
>> T funct(par...)
>> {
>> auto pCtrl = WinGetLong!Controller(hwnd);
>> ...
>> switch(msg)
>> {
>> case FirstMatch:
>> pCtrl = new Controller(hWnd, cast(CREATESTRUCT*)lParam);
>> break;
>> }
>> }
>>
>> C++ classes are in some ways more akin to D structs, in that:
>>
>> class A {};
>>
>> void foo(){
>> A bar;
>> }
>>
>> bar would be allocated on the stack in C++, while in D bar would be a
>> pointer to a class instance on the heap. (well, it would be null, but
>> when you set it to something, that something would reside on the heap)
>>
>
> Ok, that's essentially what I have, except that I used Controller pCtrl
> vice auto. WinGetLong however, is a template that calls
> GetWindowLongPtrA() and casts it's result (in this case) to Controller.
> GetWindowLongPtrA() returns LONG_PTR (aka int) and therefore fails
> miserably on the cast attempt. On the reverse, there is a WinSetLong
> that attempts to cast Controller to int for use with
> SetWindowLongPtrA(). Neither of these functions complain when I use
> Controller* but I end up with the problem of trying to initialize a
> pointer with a reference to Controller.
You almost certainly do not want a pointer to a class reference. A class
typically resides on the heap, but the reference typically does not.
Therefore, by using a pointer to a class reference, you run very high risk
of escaping stack data, leading to memory corruption.
Looking at the documentation for GetWindowLongPtr, it appears to get data
associated with a window. Likely, this information is the a pointer to
the Controller class.
I would recommend doing this:
T WinGetLong(T)(HWND hwnd)
{
return cast(T)cast(void*)GetWindowLongPtrA(hwnd, ...);
}
and
void WinSetLong(T)(HWND hwnd, T t)
{
SetWindowLongPtrA(hwnd, ..., cast(LONG_PTR)cast(void*)t);
}
where the ... is the index copied from the C++ code (guessing it's
GWLP_USERDATA?).
btw, reinterpret_cast<T>(x) is equivalent to (T)(void *)x;
-Steve
More information about the Digitalmars-d-learn
mailing list