返回

一种 C++ 转换的非正式分类

发布时间:2022-04-01 15:37:07 100
# c++# c

C++正式分类方法是直接按语法分类,分为:隐式转换和显示转换。隐式转换又称为标准转换。显示转换又分为:C风格转换、函数风格转换、C++风格转换。C++风格转换就是static_cast、dynamic_cast、const_cast和reinterpret_cast这4种。

有很长一段时间我都有这样的疑问:转换前的对象和转换后的对象是不是同一个?

现在,我引入一种非正式分类方法,分为:同对象转换和异对象转换。这两个术语是我自己编的,只是为了方便说明问题。

  • 同对象转换:转换后的对象和转换前的对象是同一个,也就是不会构造一个新的对象,还是使用原来的对象。
  • 异对象转换:转换后的对象和转换前的对象不是同一个,也就是会构造一个新的的对象。

下面分别说明这两种转换的典型情况。

一、同对象转换

所有的值类别转换及其变形都是同对象转换。

1.值类别转换

C++的值类别可以使用static_cast进行转换,属于同对象转换。注意:static_cast()和static_cast()的语义不是将一个对象转换为一个引用,而是转换对象的值类别,使其能被对应的引用绑定。

// 左值转换为左值
int a = 1;
static_cast(a) = 2;
std::cout << a << std::endl;
// 输出:2
// 左值转换为右值
int a = 1;
int&& b = static_cast(a);
b = 2;
std::cout << a << std::endl;
// 输出:2
// 右值转换为右值,转换前对象为非字面量
int a = 1;
int&& b = static_cast(static_cast(a));
b = 2;
std::cout << a << std::endl;
// 输出:2

2.借助值类别转换进行OOP转换

这种情况带有值类别转换,属于同对象转换。

// upcast
struct A
{
    int x = 1;
};

struct B : A
{
};

B b;
static_cast(b).x = 2;
std::cout << b.x << std::endl;
// 输出:2
// downcast
struct A
{
    int x = 1;
};

struct B : A
{
};

B b;
static_cast(static_cast(b)).x = 2;
std::cout << b.x << std::endl;
// 输出:2
// sidecast
struct A1
{
    virtual void f1() {}
    int x = 1;
};

struct A2
{
    virtual void f2() {}
    int y = 1;
};

struct B : A1, A2
{
};

B b;
dynamic_cast(static_cast(b)).y = 2;
std::cout << b.y << std::endl;
// 输出:2

3.借助值类别转换进行const_cast转换

这种情况带有值类别转换,也是同对象转换。注意:通过const_cast修改原本为const的对象是未定义行为。

struct A
{
    int x = 1;
};

{
    int a;
    const_cast(const_cast(a)) = 2;
    std::cout << a << std::endl;
}
{
    A a;
    const_cast(const_cast(a)).x = 2;
    std::cout << a.x << std::endl;
}
/* 输出:
2
2
*/

二、异对象转换

所有的非值类别转换都是异对象转换。

1.普通的类型转换

// 标量类型
int a = 1;
int&& b = static_cast(a);
b = 2;
std::cout << a << std::endl;
// 输出:1
// 类类型
struct A
{
    A() {
        std::cout << "A::A() " << x << std::endl;
    }
    A(const A&) {
        std::cout << "A::A(const A&) " << x << std::endl;
    }
    ~A() {
        std::cout << "A::~A() " << x << std::endl;
    }
    int x = 1;
};

A a;
A&& b = static_cast(a);
b.x = 2;
std::cout << b.x << std::endl;
/* 输出:
A::A() 1
A::A(const A&) 1
2
A::~A() 2
A::~A() 1
*/

2.指针转换

转换之后,指针本身是异对象,指针所指的对象是同对象。这种情况也包含:借助指针进行OOP转换,借助指针进行const_cast转换。

int* a = new int;
std::cout << a << std::endl;
int* && r = static_cast(a);
r = nullptr;
std::cout << a << std::endl;
/* 输出:
0x1ffdeb0 0x1ffdeb0
*/

来源:https://www.cnblogs.com/mkckr0/p/15820624.html

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线