3
#include <iostream>
using namespace std;

struct Left
{
   char i = 'k';
};

struct Right
{
   int a = 99;
};

class Bottom : public Left, public Right
{};

int main()
{
    Bottom b;

    Left l = b;
    cout << l.i;

    Right r = b;
    cout << r.a;

    return 0;    
}
// output
// k99

How did this work?

if the memory layout of Bottom is:

Left
Right
Bottom

Then slicing b (i.e. Bottom) to Left object, should be ok, but how can it work when I slice Bottom to Right object?

Note: all this would be ok if I used casting. But I did not.

9
  • 1
    You sliced out the Right part, what is the problem? In other words you called Right::Right(Right const &) with b as argument and that function can read b.a and assign this->a Commented Feb 23, 2016 at 0:47
  • When I do Right r = b I obtain a Right object from a Bottom object, without casting. so how did the compiler figure out the correct offset? Commented Feb 23, 2016 at 0:48
  • The compiler decides what the memory layout is going to be for Bottom, it knows where the parts are in just the same way it knows where any particular member variable is Commented Feb 23, 2016 at 0:49
  • 1
    "all this would be ok if I used casting" => What information would be available at compile time that a casting operator would use that a copy initialization could not also use as well? Commented Feb 23, 2016 at 0:54
  • @HostileFork Well nothing more, nothing less. I thought casting was a way for a human to tell the compiler to go and find correct offset. Otherwise, it I thought that Right r = b should end up invoking a conversion assignment Right& operator=(const Bottom&) Commented Feb 23, 2016 at 0:56

1 Answer 1

3

The Bottom to Right or to Left is a proper conversion, not just a slicing. The compiler generates code using the correct offset of the sub-object in Bottom.

This Dr.Dobbs article should be of interest to you.

Sign up to request clarification or add additional context in comments.

2 Comments

So why use static_cast<> ever then? If the compiler can figure out that I am not slicing but converting, what's the point of the cast
@Kam some conversions require a cast operator if they're deemed to be "dangerous" (and/or for historical reasons) to reduce the risk of accidentally causing undefined behaviour. For example converting base to derived requires a cast, because the base might not actually be a base of the particular derived. But derived-to-base does not require a cast because all deriveds have that base. It's nothing to do with information

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.