www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What is the design reasons for Not considering base class overloaded

reply Matthew Ong <ongbp yahoo.com> writes:
Hi,

file:///D:/JDKs/D/dmd2/html/d/function.html

Virtual Functions

All non-static non-private non-template member functions are virtual.

(global/structure/class/Interface)functions to be overridden by child class unlesss (final/sealed). This may sound inefficient, but since the D compiler knows all of the class hierarchy when generating code, all functions that are not overridden can be optimized to be non-virtual. Ok. Not an issue also. There are ways for compiler to trace the actual object being used Function Inheritance and Overriding A functions in a derived class with the same name and parameter types as a function in a base class overrides that function: ... However, when doing overload resolution, the functions in the base class are not considered: ... // ### Why Not? Since B is a subset of A, and within B itself methods inherited from A can be called. b.foo(1); // calls B.foo(long), since A.foo(int) not considered ... To consider the base class's functions in the overload resolution process, use an AliasDeclaration: ... alias A.foo foo; // ### Why the extra steps is needed for the compiler to 'know' overloaded functions from base classes? ... B b = new B(); b.foo(1); // calls A.foo(int) ------------------------------------------------------------------ // ### most developer would expect that to be the case if >All non-static non-private non-template member functions are virtual.< This seems to be self contradicting syntax. Even in scripting like bash and even the old awk, the path resolutions of a global functions uses the most newer/lasted defined automatically. ------------------------------------------------------------------ If such an AliasDeclaration is not used, the derived class's functions completely override all the functions of the same name in the base class, even if the types of the parameters in the base class functions are different. If, through implicit conversions to the base class, those other functions do get called, an std.HiddenFuncError exception is raised: ? What is the default encapsulations of a class functions? (public/private/package...) I assume that the example shown here are public because they are used in function bar? How about when the inheritance tree becomes deeper than 4? And more and more overloaded functions are in different classes? Does it mean we have to do more alias at child class at the bottom? If I am not mistaken, in C++/Java. They will choose the most bottom up closes parameter type signature match. Even in scripting All this questions are meant to understand what is the rational behind such design syntax. There is no description in those pages. How about interface function defination inheritance?? Aikkk.... I do not expect interface should be deeply inherited. -- Matthew Ong email: ongbp yahoo.com
May 24 2011
next sibling parent reply =?ISO-8859-1?Q?Ali_=C7ehreli?= <acehreli yahoo.com> writes:
On 05/24/2011 10:28 PM, Matthew Ong wrote:

 However, when doing overload resolution, the functions in the base class
 are not considered:
 ....
 // ### Why Not? Since B is a subset of A, and within B itself methods
 inherited from A can be called.
 b.foo(1); // calls B.foo(long), since A.foo(int) not considered

That is to prevent silently changing the program's behavior. b.foo(1) could happily be a call to B.foo(long) today. Imagine one of the base classes changed and now there is A.foo(int). Then our b.foo(1) would silently start calling that new function. That would cause a tough bug.
 What is the default encapsulations of a class functions?
 (public/private/package...)

private. In D, the entire module has access to private members.
 I assume that the example shown here are public because they are used in
 function bar?

No. As bar is in the same module, it has access to private members.
 How about when the inheritance tree becomes deeper than 4? And more and
 more overloaded functions are in different classes? Does it mean we have
 to do more alias at child class at the bottom?

I don't think this issue is common. Here, the decision is the safer one. Only when we know what we're doing, we can change this behavior.
 If I am not mistaken, in C++/Java. They will choose the most bottom up
 closes parameter type signature match.

Not in C++. C++ has "name hiding", which hides all of base's functions and members with the same name. Ali
May 24 2011
parent reply Jacob Carlborg <doob me.com> writes:
On 2011-05-25 08:02, Ali Çehreli wrote:
 On 05/24/2011 10:28 PM, Matthew Ong wrote:

  > However, when doing overload resolution, the functions in the base class
  > are not considered:
  > ....
  > // ### Why Not? Since B is a subset of A, and within B itself methods
  > inherited from A can be called.
  > b.foo(1); // calls B.foo(long), since A.foo(int) not considered

 That is to prevent silently changing the program's behavior. b.foo(1)
 could happily be a call to B.foo(long) today. Imagine one of the base
 classes changed and now there is A.foo(int). Then our b.foo(1) would
 silently start calling that new function. That would cause a tough bug.

  > What is the default encapsulations of a class functions?
  > (public/private/package...)

 private. In D, the entire module has access to private members.

Yes, but all declarations in classes or modules are public by default.
  > I assume that the example shown here are public because they are used in
  > function bar?

 No. As bar is in the same module, it has access to private members.

I don't where you get the private from (assuming he's talking about http://digitalmars.com/d/2.0/function.html#function-inheritance).
  > How about when the inheritance tree becomes deeper than 4? And more and
  > more overloaded functions are in different classes? Does it mean we have
  > to do more alias at child class at the bottom?

 I don't think this issue is common. Here, the decision is the safer one.
 Only when we know what we're doing, we can change this behavior.

  > If I am not mistaken, in C++/Java. They will choose the most bottom up
  > closes parameter type signature match.

 Not in C++. C++ has "name hiding", which hides all of base's functions
 and members with the same name.

 Ali

-- /Jacob Carlborg
May 24 2011
parent =?ISO-8859-1?Q?Ali_=C7ehreli?= <acehreli yahoo.com> writes:
On 05/24/2011 11:42 PM, Jacob Carlborg wrote:

 Yes, but all declarations in classes or modules are public by default.

Thanks for the correction. All this time I've been thinking the opposite. My understanding seemed correct, since most of the little programs that I've written have been in a single module. Ali
May 25 2011
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Matthew Ong:

 This may sound inefficient, but since the D compiler knows all of the 
 class hierarchy when generating code, all functions that are not 
 overridden can be optimized to be non-virtual.

This is pure theory, little more than advertisement. Also because D supports separate compilation, Walter doesn't even look interested in doing this :-)
 alias A.foo foo;  // ### Why the extra steps is needed for the compiler 
 to 'know' overloaded functions from base classes?

Others have already answered. I also suggest you to compile your code using the -w switch when possible. Bye, bearophile
May 25 2011
parent reply Matthew Ong <ongbp yahoo.com> writes:
On 5/25/2011 5:43 PM, bearophile wrote:
 alias A.foo foo;  // ### Why the extra steps is needed for the compiler
 to 'know' overloaded functions from base classes?

Others have already answered. I also suggest you to compile your code using the -w switch when possible. Bye, bearophile

That is to prevent silently changing the program's behavior. b.foo(1) 
could happily be a call to B.foo(long) today. Imagine one of the base 
classes changed and now there is A.foo(int). Then our b.foo(1) would 
silently start calling that new function. That would cause a tough bug.
Ali

Ok.. Just to protect a auto promotion error from a base class. Would not it be a better keyword such as: class A{ // assuming there is a new keyword of noinherit noinherit void foo(int x){} // all other method can be inherited in A except for this class } If such an AliasDeclaration is not used, the derived class's functions completely override all the functions of the same name in the base class, even if the types of the parameters in the base class functions are different. If, through implicit conversions to the base class, those other functions do get called, an std.HiddenFuncError exception is raised: ? What is the default encapsulations of a class functions? (public/private/package...) I assume that the example shown here are public because they are used in function bar? How about when the inheritance tree becomes deeper than 4? And more and more overloaded functions are in different classes? Does it mean we have to do more alias at child class at the bottom?<<MORE hard to solve issues. If I am not mistaken, in C++/Java. They will choose the most bottom up closes parameter type signature match. -- Matthew Ong email: ongbp yahoo.com
May 26 2011
parent Matthew Ong <ongbp yahoo.com> writes:
On 5/27/2011 2:03 PM, Matthew Ong wrote:
 Would not it be a better keyword such as:

 class A{
 // assuming there is a new keyword of noinherit
 noinherit void foo(int x){} // all other method can be inherited in A
 except for this class
 }

final. Could new keyword help function hijacking and prevented aliasing all over the place?? -- Matthew Ong email: ongbp yahoo.com
May 26 2011