Re: How to use base class & child class as parameter in one function ?

2020-05-23 Thread Vinod K Chandran via Digitalmars-d-learn

On Friday, 22 May 2020 at 22:44:17 UTC, H. S. Teoh wrote:
On Fri, May 22, 2020 at 09:39:16PM +, Vinod K Chandran via 
Digitalmars-d-learn wrote: [...]

So in the same manner, i want
void function(Base) = fnPtr wiil work with
void function(Child)


You cannot, because that's type unsafe:

class Base {}
class Derived : Base {
void derivedFunc() {}
}
class Another : Base {}

void derivedFunc(Derived d) { d.derivedFunc(); }

void function(Base) funPtr;
funPtr = derivedFunc; // suppose this was allowed

Base obj = new Another;
funPtr(obj); // crash: obj does not have derivedFunc()


T


Yeah, I understand that. And i just changed my code. Thanks for 
the guidance. :)


Re: How to use base class & child class as parameter in one function ?

2020-05-23 Thread Vinod K Chandran via Digitalmars-d-learn
On Friday, 22 May 2020 at 22:40:50 UTC, Steven Schveighoffer 
wrote:

On 5/22/20 5:39 PM, Vinod K Chandran wrote:

[...]


That is the opposite of what you are thinking. A function 
pointer has to be valid based on its parameter types. Covariant 
functions are allowed.


This is OK:

void function(Child) fptr;

void foo(Base) {}

fptr =  // OK! it's fine to call fptr with a Child, 
because it is a Base as well


void function(Base) fptr2;

void foo2(Child) {}

fptr2 =  // Error! if you called fptr2 with a Base that 
is NOT a Child, bad things will happen.


This is more clear if you actually try calling them:

fptr2(new Base); // the compiler should allow this
foo2(new Base); // but would not allow this

So why should fptr2 be allowed to point at foo2?

-Steve


Thank you for the guidance. I got the point. :)


Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/22/20 5:39 PM, Vinod K Chandran wrote:

On Friday, 22 May 2020 at 20:51:20 UTC, Steven Schveighoffer wrote:

On 5/22/20 4:04 PM, Vinod K Chandran wrote:

[...]


Yes. What you cannot do is this (which I hope doesn't compile in 
VB.net, but I wouldn't be surprised):


Dim sampleList As New List(Of Child)
sampleList.Add(New Base(10))

Which is the equivalent of what you were requesting.


Nope--
List(Of Base) will contain an instance of a Child.
So in the same manner, i want
void function(Base) = fnPtr wiil work with
void function(Child)



That is the opposite of what you are thinking. A function pointer has to 
be valid based on its parameter types. Covariant functions are allowed.


This is OK:

void function(Child) fptr;

void foo(Base) {}

fptr =  // OK! it's fine to call fptr with a Child, because it is a 
Base as well


void function(Base) fptr2;

void foo2(Child) {}

fptr2 =  // Error! if you called fptr2 with a Base that is NOT a 
Child, bad things will happen.


This is more clear if you actually try calling them:

fptr2(new Base); // the compiler should allow this
foo2(new Base); // but would not allow this

So why should fptr2 be allowed to point at foo2?

-Steve


Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, May 22, 2020 at 09:39:16PM +, Vinod K Chandran via 
Digitalmars-d-learn wrote:
[...]
> So in the same manner, i want
> void function(Base) = fnPtr wiil work with
> void function(Child)

You cannot, because that's type unsafe:

class Base {}
class Derived : Base {
void derivedFunc() {}
}
class Another : Base {}

void derivedFunc(Derived d) { d.derivedFunc(); }

void function(Base) funPtr;
funPtr = derivedFunc; // suppose this was allowed

Base obj = new Another;
funPtr(obj); // crash: obj does not have derivedFunc()


T

-- 
Век живи - век учись. А дураком помрёшь.


Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread Vinod K Chandran via Digitalmars-d-learn
On Friday, 22 May 2020 at 20:51:20 UTC, Steven Schveighoffer 
wrote:

On 5/22/20 4:04 PM, Vinod K Chandran wrote:

[...]


Yes. What you cannot do is this (which I hope doesn't compile 
in VB.net, but I wouldn't be surprised):


Dim sampleList As New List(Of Child)
sampleList.Add(New Base(10))

Which is the equivalent of what you were requesting.

-Steve

Nope--
List(Of Base) will contain an instance of a Child.
So in the same manner, i want
void function(Base) = fnPtr wiil work with
void function(Child)



Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, May 22, 2020 at 08:55:45PM +, Vinod K Chandran via 
Digitalmars-d-learn wrote:
> On Friday, 22 May 2020 at 20:06:20 UTC, Adam D. Ruppe wrote:
> > On Friday, 22 May 2020 at 20:04:24 UTC, Vinod K Chandran wrote:
> > > sampleList.Add(New Child(10.5)) Is this possible in D without
> > > casting ?
> > 
> > Direct translation of this code works just fine in D.
> 
> Yeah, my bad. I just checked in D. But think inherited type difference
> is a problem in function pointer's parameters only.
> alias EvtFuncPtr = void function(EventArgs);
> Now, this EvtFuncPtr won't allow any derived classes of EventArgs as
> parameter. That's the problem i am facing.
[...]

So you're basically saying:

void function(DerivedClass)

cannot implicitly convert to:

void function(BaseClass)

right?

This is as it should be:

class Base { ... }
class Derived : Base { ... }
class Another : Base { ... }

void baseFunc(Base) { ... }
void derivedFunc(Derived) { ... }

void function(Base) funcPtr;
funcPtr = baseFunc; // OK
funcPtr = derivedFunc;  // Not allowed

Why is it bad to assign derivedFunc to funcPtr?  Consider this:

Base obj = new Another;
funcPtr = baseFunc;
funcPtr(obj);   // OK, because Another is a subtype of Base

funcPtr = derivedFunc; // suppose this was allowed
funcPtr(obj);   // Uh oh, derivedFunc receives an argument of
// type Another which is not a subtype of
// Derived

So, it's not permissible to allow assigning derivedFunc to funcPtr
without a cast.


T

-- 
Indifference will certainly be the downfall of mankind, but who cares? -- 
Miquel van Smoorenburg


Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread Vinod K Chandran via Digitalmars-d-learn

On Friday, 22 May 2020 at 20:06:20 UTC, Adam D. Ruppe wrote:

On Friday, 22 May 2020 at 20:04:24 UTC, Vinod K Chandran wrote:
sampleList.Add(New Child(10.5)) Is this possible in D without 
casting ?


Direct translation of this code works just fine in D.


Yeah, my bad. I just checked in D. But think inherited type 
difference is a problem in function pointer's parameters only.

alias EvtFuncPtr = void function(EventArgs);
Now, this EvtFuncPtr won't allow any derived classes of EventArgs 
as parameter. That's the problem i am facing. What about a 
template ?


alias EvtFuncPtr = void function(T)(T = EventArgs);
This is not compiled.


Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/22/20 4:04 PM, Vinod K Chandran wrote:

On Friday, 22 May 2020 at 16:12:12 UTC, Steven Schveighoffer wrote:

On 5/22/20 9:10 AM, Vinod K Chandran wrote:

On Friday, 22 May 2020 at 12:21:25 UTC, rikki cattermole wrote:

if (Child child = cast(Child)parent) {
assert(child !is null);
}


Actually, problem occurs in addHandler function. It expects an 
argument of type "EventArgs", not MouseEventArgs.


Yes, because what if you did this with your function:

fnp(new EventArgs(...));

It would be called with the type being implicitly cast to the child 
type without that being true.


What Rikki was recommending is that you write your handler like this:

void onClick(EventArgs e){
    if(auto me = cast(MouseEventArgs)e) {
    log("form clicked on x = ", me.x, ", and y = ", me.y);
    }
}

Actually, if you are certain it's a programming error for onClick to 
be called with a different type of event args, I'd do:


void onClick(EventArgs e){
    auto me = cast(MouseEventArgs)e;
    assert(me !is null, "Error, onClick called with invalid event type");
    log("form clicked on x = ", me.x, ", and y = ", me.y);
}


Thanks for the answer. I understand that, in D, derived class and base 
class are not the same as in vb.net or any other language. (Please 
correct me if i am wrong).

In vb.net, assume that i have a class setup like this--
Public Class Base
     Public Property SampleInt As Integer
End Class

Public Class Child : Inherits Base
     Public Property SampleDouble As Double
End Class
//Assume that i have a list of Base class like this--
Dim sampleList As New List(Of Base)
// Now, i can use this list like this--
sampleList.Add(New Child(10.5)) Is this possible in D without casting ?



Yes. What you cannot do is this (which I hope doesn't compile in VB.net, 
but I wouldn't be surprised):


Dim sampleList As New List(Of Child)
sampleList.Add(New Base(10))

Which is the equivalent of what you were requesting.

-Steve


Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 22 May 2020 at 20:04:24 UTC, Vinod K Chandran wrote:
sampleList.Add(New Child(10.5)) Is this possible in D without 
casting ?


Direct translation of this code works just fine in D.


Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread Vinod K Chandran via Digitalmars-d-learn
On Friday, 22 May 2020 at 16:12:12 UTC, Steven Schveighoffer 
wrote:

On 5/22/20 9:10 AM, Vinod K Chandran wrote:

On Friday, 22 May 2020 at 12:21:25 UTC, rikki cattermole wrote:

if (Child child = cast(Child)parent) {
assert(child !is null);
}


Actually, problem occurs in addHandler function. It expects an 
argument of type "EventArgs", not MouseEventArgs.


Yes, because what if you did this with your function:

fnp(new EventArgs(...));

It would be called with the type being implicitly cast to the 
child type without that being true.


What Rikki was recommending is that you write your handler like 
this:


void onClick(EventArgs e){
if(auto me = cast(MouseEventArgs)e) {
log("form clicked on x = ", me.x, ", and y = ", me.y);
}
}

Actually, if you are certain it's a programming error for 
onClick to be called with a different type of event args, I'd 
do:


void onClick(EventArgs e){
auto me = cast(MouseEventArgs)e;
assert(me !is null, "Error, onClick called with invalid 
event type");

log("form clicked on x = ", me.x, ", and y = ", me.y);
}


Thanks for the answer. I understand that, in D, derived class and 
base class are not the same as in vb.net or any other language. 
(Please correct me if i am wrong).

In vb.net, assume that i have a class setup like this--
Public Class Base
Public Property SampleInt As Integer
End Class

Public Class Child : Inherits Base
Public Property SampleDouble As Double
End Class
//Assume that i have a list of Base class like this--
Dim sampleList As New List(Of Base)
// Now, i can use this list like this--
sampleList.Add(New Child(10.5)) Is this possible in D without 
casting ?




Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/22/20 9:10 AM, Vinod K Chandran wrote:

On Friday, 22 May 2020 at 12:21:25 UTC, rikki cattermole wrote:

if (Child child = cast(Child)parent) {
assert(child !is null);
}


Actually, problem occurs in addHandler function. It expects an argument 
of type "EventArgs", not MouseEventArgs.


Yes, because what if you did this with your function:

fnp(new EventArgs(...));

It would be called with the type being implicitly cast to the child type 
without that being true.


What Rikki was recommending is that you write your handler like this:

void onClick(EventArgs e){
if(auto me = cast(MouseEventArgs)e) {
log("form clicked on x = ", me.x, ", and y = ", me.y);
}
}

Actually, if you are certain it's a programming error for onClick to be 
called with a different type of event args, I'd do:


void onClick(EventArgs e){
auto me = cast(MouseEventArgs)e;
assert(me !is null, "Error, onClick called with invalid event type");
log("form clicked on x = ", me.x, ", and y = ", me.y);
}


Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread Vinod K Chandran via Digitalmars-d-learn

On Friday, 22 May 2020 at 12:21:25 UTC, rikki cattermole wrote:

if (Child child = cast(Child)parent) {
assert(child !is null);
}


Actually, problem occurs in addHandler function. It expects an 
argument of type "EventArgs", not MouseEventArgs.


Re: How to use base class & child class as parameter in one function ?

2020-05-22 Thread rikki cattermole via Digitalmars-d-learn

if (Child child = cast(Child)parent) {
assert(child !is null);
}


How to use base class & child class as parameter in one function ?

2020-05-22 Thread Vinod K Chandran via Digitalmars-d-learn




Hi all,
I have a windows gui setup like this;

class EventArgs {} \\ Base class for all messages
class MouseEventArgs : EventArgs {	// child class for handling 
mouse messages

...
int x;
int y;
this(WPARAM wpm, LPARAM lpm){
this.x = xFromLparam(lpm);
this.y = yFromLparam(lpm);
}
}

alias EvtFuncPtr = void function(EventArgs); // function pointer

struct MsgHandler {
uint message ;
HWND handle ;
bool isActive ;
EvtFuncPtr fnPtr;
}
// Then in my window class...
void addHandler(uint we, EvtFuncPtr fnp){ // This is error point.
auto mh = MsgHandler();
mh.handle = this.mHandle;
mh.message = we;
mh.fnPtr = fnp;
mh.isActive = true;
	this.msgHandlerList ~= mh;  // This is a list in 
window class.	

}

// And in the WndProc...
auto thisWin = findWindowClass(hWnd);  // get the window class 
with hWnd.
auto mh = thisWin.findHandler(hWnd, message);// get the event 
handler for this message & hWnd

if(mh.isActive) { // if there is an event handler fixed,
switch (message){
   case 512 : .. case 526 :  // if it's a Mouse messages
auto ea = new MouseEventArgs(wParam, lParam);
mh.fnPtr(ea);   // execute that event handler function
break;
   default : break;
}
}

// And this is the window creation site...
auto app = new Application() ;
auto frm = new Window(app) ;
frm.createWindow() ;

frm.addHandler(frm.load, );
frm.addHandler(frm.Click, );

void onLoad(EventArgs e){
log("form is loaded...");
}
void onClick(MouseEventArgs e){	 // Compiler wants to change the 
MouseEventArgs with EventArgs.

log("form clicked on x = ", e.x, ", and y = ", e.y);
}

I wrote  EventArgs as the parameter type in function pointer but 
i want to use it's child classes also. But i can't.