C++ 类型转换

Let’s begin with a review of casting syntax, because there are usually

three different ways to write the same cast. C-style casts look like this:

(T) expression

// cast expression to be of type T

Function-style casts use this syntax:

T(expression)

// cast expression to be of type T

 

There is no difference in meaning between these forms; it’s purely a

matter of where you put the parentheses. I call these two forms oldstyle casts.

C++ also offers four new cast forms (often called new-style or C++-style

casts):

const_cast<T>(expression)

dynamic_cast<T>(expression)

reinterpret_cast<T>(expression)

static_cast<T>(expression)

Each serves a distinct purpose:

■ const_cast is typically used to cast away the constness of objects. It

is the only C++-style cast that can do this.

■ dynamic_cast is primarily used to perform “safe downcasting,” i.e.,

to determine whether an object is of a particular type in an inheritance hierarchy. It is the only cast that cannot be performed using the old-style syntax. It is also the only cast that may have a

significant runtime cost. (I’ll provide details on this a bit later.)

■ reinterpret_cast is intended for low-level casts that yield implementation-dependent (i.e., unportable) results, e.g., casting a pointer

to an int. Such casts should be rare outside low-level code. I use it

only once in this book, and that’s only when discussing how you

might write a debugging allocator for raw memory (see Item 50).

■ static_cast can be used to force implicit conversions (e.g., non-const

object to const object (as in Item 3), int to double, etc.). It can also be

used to perform the reverse of many such conversions (e.g., void*

pointers to typed pointers, pointer-to-base to pointer-to-derived),

though it cannot cast from const to non-const objects. (Only

const_cast can do that.)

The old-style casts continue to be legal, but the new forms are preferable. First, they’re much easier to identify in code (both for humans

and for tools like grep), thus simplifying the process of finding places

in the code where the type system is being subverted. Second, the

more narrowly specified purpose of each cast makes it possible for

compilers to diagnose usage errors. For example, if you try to cast

away constness using a new-style cast other than const_cast, your

code won’t compile.

 

用static_cast<*this>()表明类型转换的隐含问题。

转换之后操作的并非原有对象,而是一个副本,是一个临时变量,无法取地址,右值。

class Base
{
public:
    Base(int _i) :i(_i)
    {}
    virtual void onReSize(int _i)
    {
        i = _i;
    }
    int i = 0;
};

class Derived : public Base
{
public:
    Derived(int _i, int _j):Base(_i), j(_j)
    {}
    void onReSize(int _i)
    {
        static_cast<Base>(*this).onReSize(_i);
        j = _i * 2;
    }
    void printSize()
    {
        std::cout << i << j;
    }
    int j = 0;
};

int main()
{
    Base ba(6);

    Derived de(10, 22);
    de.onReSize(99);

    auto x = dynamic_cast<Base*>(&de);
    x->onReSize(88);    // 调用扩展类
    auto y = dynamic_cast<Base*>(&ba);
    y->onReSize(66);    // 调用基类,x与y均只有onResize函数

    auto z = dynamic_cast<Derived*>(&ba);   // z为nullptr
    if (z != nullptr)
    {
        z->onReSize(77);
        z->printSize();
    }

    auto zz = dynamic_cast<Derived*>(&de);
    zz->onReSize(99);
    zz->printSize();

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值