dodoptak
dodoptak

Reputation: 69

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;
}

Upvotes: 2

Views: 165

Answers (2)

ex-bart
ex-bart

Reputation: 1392

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.

Upvotes: 1

Jarod42
Jarod42

Reputation: 217810

sizeof(*((*ptr1).clone())) is a compile time value, and expression is not executed.

so here we have sizeof(*((*std::declval<A*>()).clone())) which is sizeof(A) (we use A::clone() which returns A*).

Upvotes: 2

Related Questions