Variant return type Upcasting Overriding c++

Variant return type Upcasting Overriding c++

我在以下示例中使用 clone() 方法时遇到问题。我曾预计 sizeof(*((*ptr1).clone()))b1 相同,而 sizeof(*(ptr2.clone()))c1 相同,但事实并非如此。他们是sizeof(a1)。我错过了什么?

这是代码。

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

sizeof(*((*ptr1).clone()))为编译时值,表达式不执行。

所以这里我们有 sizeof(*((*std::declval<A*>()).clone()))sizeof(A)(我们使用 A::clone() 其中 returns A*)。

sizeof只考虑其参数的静态类型,不考虑动态类型。因此 sizeof 的参数可以是未评估的操作数,并且 sizeof 的结果不依赖于任何 运行 时间信息(例如动态类型信息所需的 vtables)。因此 sizeof 的结果始终是一个编译时常量表达式,适用于例如作为模板参数。

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