Re: function defined with base class return derived class object when called with a derived class
On 1 Aug., 00:55, B?RCI Norbert wrote:
Is there any possible way to define a member function of class A, but
when called with an object of class B (derived from A), it somehow
return the object as B?
Given:
class A
{
public:
A & memA() { /* ... */ return *this; }
};
class B : public A
{
public:
B & memA() { A::memA(); return *this; }
B & memB() { /* ... */ return *this; }
};
I want to do the following:
use_it(B().memA().memB());
This should work with the line I inserted above. I see that you
already considered this below.
I know that it does not work with the definitions above, but I think
if I call memA with a B object, the expression should be considered as
an object of type B.
Why? The function's signature doesn't say anything about what
reference it will be. It could refer to any object and is NOT
restricted to *this.
There is no semantic problem with this: if I call
memA it will do something with the A part of B. And there is no
syntactic problem either: any code that was correct before, should
compile and run as before: if something was compilable with (B().memA
()) considered as type A it should compile with the same
expression considered as a B also.
Wrong. A::memA() might return a reference to some other object of type
A that is always of type A and not B.
Worse, there is no *_cast which is able to do the trick, except when I
use a pointer:
use_it( static_cast<B*>(&(B().memA()))->memB() );
Wrong. Try static_cast<B&>
class B : public A
{
public:
B & memA() { A::memA(); return *this; }
void memB() { /*...*/ }
};
But I consider this again a code bloat, especially when there are lot
of base class member functions which I have to "repeat" this way just
to achieve my goal.
IDEA: To summarize, I beleive that ``return *this'' should mean to
return the object it was called with, not to return that part of the
object that was known when the function was defined.
But "return *this;" is not part of the function's signature.
auto A::A() { /* ... */ return *this; }
At some point I was actually considering something like this:
class A {
public:
auto foo() -> this;
};
to fix the problem of dangling references in cases like
A const& r = A().foo();
For derived types the return type could be automatically covariant
like you suggested. The return value could even retain its
"valueness" (lvalues -> lvalue, rvalue -> rvalue).
The "natural" extension for free functions:
auto flip(-> string io);
{ // ^^
std::reverse(io.begin(),io.end());
}
PROS: Reduces copying & avoids dangling references at the same time
for all functions that can work "in-place".
CONS: Introduces new types of functions that need to be supported
by function pointers and template argument deduction. It
will probably make generic programming horrible. I don't see
how perfect forwarding would be possible.
I've come to the conclusion that it's not a good idea to introduce a
whole new class of function types.
Cheers!
SG
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]