You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A base type subobject is declared the same as any member object, but with the name `this`. See test case example in this commit, pasted below for convenience
Note that `:` continues to be pronounces "is a"... e.g., `f: () -> int` is pronounced as "f is a function returning int," `v: vector<int>` as "v is a vector<int>", `this: Shape` as "this object is a Shape."
This is consistent because in Cpp2 I'm pursuing the experiment of making inheritance be always `public` and therefore inheritance should always model IS-A substitutability.
- Why not protected inheritance? Because the only theoretical use of that I know of is to enable IS-A substitutability only for code within the same class hierarchy, and I know of no actual use of that feature.
- Why not private inheritance? Because it is anti-recommended, nearly always that should be a private data member instead, and the main reason to use a private base is to make that data member outlive a base class object... which is already covered in Cpp2 because all subobjects (bases and members) can be declared in any order. In this initial checkin, if there are any non-base subobjects (ordinary data members) that are declared before base subobjects (base classes), as an implementation detail those non-bases are emitted as private base classes via a helper wrapper that prevents their interface (functions) from leaking into the type.
If a type has base classes, I don't generate assignment from construction. This is because polymorphic types usually don't want (nonvirtual) assignment, and so base classes generally don't provide assignment so a generated memberwise assignment wouldn't work anyway. However, as of this commit, I don't currently ban a user explicitly writing their own assignment operator if they want to, which will be fine as long as `Base::operator=` memberwise calls are available.
Abstract virtual functions are simply virtual functions that have no initializer. (All other functions in Cpp2 must have an initializer.)
Also corrected the namespace alias representation to use id-expression
### Test case (pasted for convenience)
```
Human: type = {
operator=: (out this) = {}
speak: (virtual this);
}
N: namespace = {
Machine: type = {
operator=: (out this, id: std::string) = {}
work: (virtual this);
}
}
Cyborg: type = {
name: std::string;
this: Human = ();
this: N::Machine;
operator=: (out this, n: std::string) = {
name = n;
N::Machine = "Acme Corp. engineer tech";
std::cout << "(name)$ checks in for the day's shift\n";
}
speak: (override this) =
std::cout << "(name)$ cracks a few jokes with a coworker\n";
work: (override this) =
std::cout << "(name)$ carries some half-tonne crates of Fe2O3 to cold storage\n";
operator=: (move this) =
std::cout << "Tired but satisfied after another successful day, (name)$ checks out and goes home to their family\n";
}
make_speak: ( h: Human ) = {
std::cout << "-> [vcall: make_speak] ";
h.speak();
}
do_work: ( m: N::Machine ) = {
std::cout << "-> [vcall: do_work] ";
m.work();
}
main: () = {
c: Cyborg = "Parsnip";
c.make_speak();
c.do_work();
}
```
Output:
```
Parsnip checks in for the day's shift
-> [vcall: make_speak] Parsnip cracks a few jokes with a coworker
-> [vcall: do_work] Parsnip carries some half-tonne crates of Fe2O3 to cold storage
Tired but satisfied after another successful day, Parsnip checks out and goes home to their family
```
0 commit comments