Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Andreas Leitgeb Newsgroups: comp.lang.java.programmer Subject: Re: How to assign an object to another in it method? Date: Thu, 13 Jul 2017 17:19:47 -0000 (UTC) Organization: A noiseless patient Spider Lines: 55 Message-ID: References: <46334961-cc18-491f-828c-32e7401c7832@googlegroups.com> Reply-To: avl@logic.at Injection-Date: Thu, 13 Jul 2017 17:19:47 -0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="891ec2ce37e0ba46fd2b2385f5ad4a6c"; logging-data="18361"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18/nhlKVMtat7miv/bhF38C" User-Agent: slrn/1.0.2 (Linux) Cancel-Lock: sha1:200spQ+xeo+5f2beSWZjTLRJIUM= Xref: csiph.com comp.lang.java.programmer:36902 Jerry Stuckle wrote: > On 7/13/2017 6:08 AM, Andreas Leitgeb wrote: >> I brought up the problem(imho) of overriding methods with >> changed default values for arguments, which in C++ are static >> type matter (non-polymorphic). > Incorrect. Methods with default values are also polymorphic. #include struct A { virtual void foo(int i = 42) { printf("A: %d\n", i); } }; struct B : public A { void foo(int i = 54) { printf("B: %d\n", i); } }; int main() { A a; a.foo(); B b; b.foo(); A *pa = &a; pa->foo(); pa = &b; pa->foo(); } Compiling and running it yields: A: 42 B: 54 A: 42 B: 42 The last one polymorphically(because of the 'virtual') calls B::foo(int), but passss it A::foo's default value, as the pointer is A-typed. So, I still consider my claim as correct. >> Ideally, a subclass should be allowed to "remove" methods in a way that the >> compiler could preempt some mistakes: "If you already know you're dealing >> with a Square, then rather use Square's setDimension(int length) instead of >> the inherited setDimension(int,int)". Obviously the compiler couldn't catch >> cases like ((Rectangle)square).setDimensions(1,2), so not all runtime >> errors can be prevented at compile time, but at least some. > > So what happens when you pass the derived object to a method expecting a > base object? Then it would end up running that "disabled" method, which will do whatever is coded into it: e.g. always throw an error, or spend some effort to determine still-sensible calls, for which to do something sensible. In C++ you can declare an override as private - if it was virtual within the super class, it can still be called through super class, but not through its own type. In the example above, add a "private:" into B's body before void foo..., and since the b.foo() call becomes invalid, comment it out. The last call will still invoke the now private B::foo (and still with 42 as default). I don't like the non-polymorphic default values of C++, but I do like that in C++ a subclass *can* get rid of its inherited baggage.