Search code examples
c++polymorphismoverridingupcasting

Variant return type Upcasting Overriding c++


I have problem with clone() method in the following example. I have expected that sizeof(*((*ptr1).clone())) would be the same as b1 and sizeof(*(ptr2.clone())) would be the size of c1 but they are not. They are sizeof(a1). What am I missing?

Here is the code.

class A
{int a;
public:
    virtual A * clone() {return this;}
};

class B : public A
{int b,c;
public:
    B * clone() {return this;}
};

class C : public A
{int b,c,d;
public:
    C * clone() {return this;}
};

int main()
{
    A a1;
    B b1;
    C c1;
    A * ptr1 = &b1;
    A & ptr2 = c1;
    std::cout << "sizeof(a1) = " << sizeof(a1) << '\n';
    std::cout << "sizeof(b1) = " << sizeof(b1) << '\n';
    std::cout << "sizeof(*(b1.clone())) = " << sizeof(*(b1.clone())) << '\n';
    std::cout << "sizeof(c1) = " << sizeof(c1) << '\n';
    std::cout << "sizeof(*((*ptr1).clone()))" << sizeof(*((*ptr1).clone())) << '\n';
    std::cout << "sizeof(*(ptr2.clone()))" << sizeof(*(ptr2.clone())) << '\n';
    return 0;
}

Solution

  • sizeof only takes the static type of its argument into account, not the dynamic type. Thus the argument to sizeof can be an unevaluated operand, and the result of sizeof does not depend on any run-time information (such as vtables required for dynamic type information). And so the result of sizeof is always a compile-time constant expression, suitable to be used e.g. as a template argument.

    See C++11: §5.3.3 [expr.sizeof]/2.