Skip to content

Commit f88fca2

Browse files
ntreldlang-bot
authored andcommitted
[spec/function.dd] Improve *Virtual Functions* section
Move simple overriding example from 'Function Inheritance and Overriding'. This introduces `override` before the next more complex example about virtual vs non-virtual methods. Explain that `override` is required and that it can catch bugs. Use list for kinds of non-virtual functions. Simplify examples a bit. Move paragraph about Objective-C to end of section. Add 'Covariance' subheading. Add 'Calling Base Class Methods' subheading & tweak wording. Change 'Function Inheritance and Overriding' subheading to 'Overload Sets and Overriding'. Default Values)) Add 'Default Values', 'Inherited Attributes', 'Restrictions' subheadings. 'Function Parameters' section: Add subheading & move `this` reference and Obj-C selector docs here. attributes.dd: Remove info and link to 'Virtual Functions'.
1 parent b06a064 commit f88fca2

File tree

2 files changed

+75
-103
lines changed

2 files changed

+75
-103
lines changed

spec/attribute.dd

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -549,30 +549,7 @@ $(H2 $(LNAME2 return, $(D return) Attribute))
549549

550550
$(H2 $(LNAME2 override, $(D override) Attribute))
551551

552-
$(P The $(D override) attribute applies to virtual functions.
553-
It means that the function must override a function with the
554-
same name and parameters in a base class. The override attribute
555-
is useful for catching errors when a base class's member function
556-
gets its parameters changed, and all derived classes need to have
557-
their overriding functions updated.
558-
)
559-
560-
---------------
561-
class Foo
562-
{
563-
int bar();
564-
int abc(int x);
565-
}
566-
567-
class Foo2 : Foo
568-
{
569-
override
570-
{
571-
int bar(char c); // error, no bar(char) in Foo
572-
int abc(int x); // ok
573-
}
574-
}
575-
---------------
552+
$(P See $(DDSUBLINK spec/function, virtual-functions, Virtual Functions).)
576553

577554
$(H2 $(LNAME2 static, $(D static) Attribute))
578555

spec/function.dd

Lines changed: 74 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -954,26 +954,45 @@ $(H2 $(LNAME2 virtual-functions, Virtual Functions))
954954

955955
$(P Virtual functions are class member functions that are called indirectly through a
956956
function pointer table, called a `vtbl[]`, rather than directly.
957+
Member functions that are virtual can be overridden in a derived class:
957958
)
958959

959-
$(P Member functions that are virtual can be overridden, unless they are `final`.
960-
)
960+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
961+
------
962+
class A
963+
{
964+
void foo(int x) {}
965+
}
961966

962-
$(P Struct and union member functions are not virtual.
963-
)
967+
class B : A
968+
{
969+
override void foo(int x) {}
970+
//override void foo() {} // error, no foo() in A
971+
}
964972

965-
$(P Static member functions are not virtual.
966-
)
973+
void test()
974+
{
975+
A a = new B();
976+
a.foo(1); // calls B.foo(int)
977+
}
978+
------
979+
)
967980

968-
$(P Member functions which are $(D private) or $(D package) are not virtual.
969-
)
981+
$(P The `override` attribute is required when overriding a function.
982+
This is useful for catching errors when a base class's member function
983+
has its parameters changed, and all derived classes need to have
984+
their overriding functions updated.)
970985

971-
$(P Member template functions are not virtual.
986+
$(P The following are not virtual:)
987+
$(UL
988+
$(LI Struct and union member functions)
989+
$(LI `final` member functions)
990+
$(LI $(DDSUBLINK attribute, static, `static`) member functions)
991+
$(LI Member functions which are $(D private) or $(D package))
992+
$(LI Member template functions)
972993
)
973994

974-
$(P Member functions with `Objective-C` linkage are virtual even if marked
975-
with `final` or `static`.
976-
)
995+
$(P $(B Example:))
977996

978997
------
979998
class A
@@ -992,22 +1011,23 @@ class B : A
9921011
int abc() { ... } // ok, A.abc is not virtual, B.abc is virtual
9931012
}
9941013

995-
void test(A a)
1014+
void test()
9961015
{
1016+
A a = new B;
9971017
a.def(); // calls B.def
9981018
a.foo(); // calls A.foo
9991019
a.bar(); // calls A.bar
10001020
a.abc(); // calls A.abc
10011021
}
1002-
1003-
void func()
1004-
{
1005-
B b = new B();
1006-
test(b);
1007-
}
10081022
------
10091023

1010-
$(P The overriding function may be covariant with the overridden function.
1024+
$(P Member functions with `Objective-C` linkage are virtual even if marked
1025+
with `final` or `static`, and can be overridden.
1026+
)
1027+
1028+
$(H3 $(LNAME2 covariance, Covariance))
1029+
1030+
$(P An overriding function may be covariant with the overridden function.
10111031
A covariant function has a type that is implicitly convertible to the
10121032
type of the overridden function.
10131033
)
@@ -1030,21 +1050,12 @@ class Bar : Foo
10301050
------
10311051
)
10321052

1033-
$(P
1034-
Non-static (i.e., virtual functions and `final` member
1035-
functions) all have a hidden parameter called the
1036-
`this` reference, which refers to the class object for which
1037-
the function is called.
1038-
)
1053+
$(H3 $(LNAME2 base-methods, Calling Base Class Methods))
10391054

1040-
$(P
1041-
Functions with `Objective-C` linkage have an additional hidden,
1042-
unnamed, parameter which is the selector it was called with.
1043-
)
1044-
1045-
$(P To directly call a base member function (i.e., avoid dynamic
1046-
binding on member function call), insert the base class name before
1047-
the member function name. For example:
1055+
$(P To directly call a member function of a base class `Base`,
1056+
write `Base.` before the function name.
1057+
This avoids dynamic dispatch through a function pointer. For
1058+
example:
10481059
)
10491060

10501061
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
@@ -1086,33 +1097,7 @@ void main()
10861097
known, such as if it is `final`, it can use a direct call instead.
10871098
)
10881099

1089-
$(H3 $(LNAME2 function-inheritance, Function Inheritance and Overriding))
1090-
1091-
$(P A function in a derived class with the same name and covariant
1092-
with a function in a base class overrides that function:)
1093-
1094-
------
1095-
class A
1096-
{
1097-
int foo(int x) { ... }
1098-
}
1099-
1100-
class B : A
1101-
{
1102-
override int foo(int x) { ... }
1103-
}
1104-
1105-
void test()
1106-
{
1107-
B b = new B();
1108-
bar(b);
1109-
}
1110-
1111-
void bar(A a)
1112-
{
1113-
a.foo(1); // calls B.foo(int)
1114-
}
1115-
------
1100+
$(H3 $(LNAME2 function-inheritance, Overload Sets and Overriding))
11161101

11171102
$(P When doing overload resolution, the functions in the base
11181103
class are not considered, as they are not in the same
@@ -1134,9 +1119,9 @@ class B : A
11341119
void test()
11351120
{
11361121
B b = new B();
1137-
b.foo(1); // calls B.foo(long), since A.foo(int) not considered
1138-
A a = b;
1122+
b.foo(1); // calls B.foo(long), since A.foo(int) is not considered
11391123

1124+
A a = b;
11401125
a.foo(1); // issues runtime error (instead of calling A.foo(int))
11411126
}
11421127
------
@@ -1160,12 +1145,7 @@ class B : A
11601145

11611146
void test()
11621147
{
1163-
B b = new B();
1164-
bar(b);
1165-
}
1166-
1167-
void bar(A a)
1168-
{
1148+
A a = new B();
11691149
a.foo(1); // calls A.foo(int)
11701150
B b = new B();
11711151
b.foo(1); // calls A.foo(int)
@@ -1180,6 +1160,8 @@ void bar(A a)
11801160
implicit conversions to the base class, those other functions do
11811161
get called:
11821162
)
1163+
1164+
$(SPEC_RUNNABLE_EXAMPLE_FAIL
11831165
---
11841166
class A
11851167
{
@@ -1188,22 +1170,19 @@ class A
11881170
}
11891171
class B : A
11901172
{
1191-
void set(long i) { }
1173+
override void set(long i) { }
11921174
}
11931175

1194-
void foo(A a)
1176+
void test()
11951177
{
1196-
int i;
1178+
A a = new B;
11971179
a.set(3); // error, use of A.set(int) is hidden by B
11981180
// use 'alias set = A.set;' to introduce base class overload set
1199-
assert(i == 1);
1200-
}
1201-
1202-
void main()
1203-
{
1204-
foo(new B);
12051181
}
12061182
---
1183+
)
1184+
1185+
$(H3 $(LNAME2 override-defaults, Default Values))
12071186

12081187
$(P A function parameter's default value is not inherited:)
12091188

@@ -1236,6 +1215,8 @@ void test()
12361215
}
12371216
------
12381217

1218+
$(H3 $(LNAME2 inheriting-attributes, Inherited Attributes))
1219+
12391220
$(P An overriding function inherits any unspecified $(GLINK FunctionAttributes)
12401221
from the attributes of the overridden function.)
12411222

@@ -1258,6 +1239,8 @@ void main()
12581239
------
12591240
)
12601241

1242+
$(H3 $(LNAME2 override-restrictions, Restrictions))
1243+
12611244
$(P The attributes
12621245
$(LINK2 attribute.html#disable, $(D @disable)) and
12631246
$(LINK2 attribute.html#deprecated, $(D deprecated))
@@ -1281,7 +1264,6 @@ void main()
12811264
}
12821265
---
12831266

1284-
$(P Static functions with `Objective-C` linkage are overridable.)
12851267

12861268
$(H2 $(LNAME2 inline-functions, Inline Functions))
12871269

@@ -2414,6 +2396,19 @@ $(H4 $(LNAME2 lazy_variadic_functions, Lazy Variadic Functions))
24142396
parameter. This will prevent a closure being generated for the delegate,
24152397
as `scope` means the delegate will not escape the function.)
24162398

2399+
$(H3 $(LNAME2 this-reference, `this` Reference))
2400+
2401+
$(P
2402+
Non-static member functions all have a hidden parameter called the
2403+
`this` reference, which refers to the object for which
2404+
the function is called.
2405+
)
2406+
2407+
$(P
2408+
Functions with `Objective-C` linkage have an additional hidden,
2409+
unnamed, parameter which is the selector it was called with.
2410+
)
2411+
24172412

24182413
$(H2 $(LEGACY_LNAME2 Local Variables, local-variables, Local Variables))
24192414

0 commit comments

Comments
 (0)