const_cast 和 static_cast

C++-cast系列类型转换

C++-static_cast系列类型转换.jpg

C++-const_cast

int x = 65536;
(short &)x = 65535;
cout<<x;
int main()
{
    const int x = 0;
    *(int*)&x = 2;
    cout << "x = " << x << endl;        // x = 0
    (int&)x = 3;
    int y = x;
    cout << "y = " << y << endl;        // y = 0
    const_cast<int&>(x) = 10;
    y = x;
    cout << "y = " << y << endl;        // y = 0
    
    return 0;
}
struct T{
    int x = 0;
    const int y = 0;
    int q() const{
        *(int*)&y = y + 1;
        return y;
    }
};
int main()
{
    T m;
    const T n;
    int x = m.q();  // 修改可写对象 m 的只读成员 m.y 的值
    cout << m.y << endl;    // 1
    x = n.q();      // 修改只读对象 n 的只读成员 n.y 的值
    cout << n.y << endl;    // 1
    
    return 0;
}
// x 为const全局变量,即全局只读变量,内存分配在受保护的区域
const int x = 0;                            
// y 为可写易变全局变量
volatile int y = 0;

int main()
{
    // z 为const自动变量,内存分配在受保护的区域
    const int z = 0;
    // 正确:x有const但被忽略,因为现在只读x的值,转换目标为右值
    int w = static_cast<int>(x); 
    cout << "w = " << w << endl;
    // 错误:转换结果为右值,不能对其赋值
    // static_cast<int>(x) = 0;
    // 错误:不能去除x的const只读属性,转换目标为左值
    // static_cast<int&>(x) = 0;
    // 错误:转换结果为右值,不能对其赋值
    // static_cast<int>(w) = 0;
    // 正确:转换为有址传统左值引用,可添加volatile
    static_cast<volatile int&>(w) = 1; 
    cout << "w = " << w << endl;
    // 错误:无法去除const,将原类型const int*转换为int*,转换用作左值
    // *static_cast<int*>(&x) = 0;
    // 错误:无法去除全局变量y的volatile属性
    // static_cast<int&>(y) = 0;
    int&& p = 0;
    static_cast<int&>(p) = 4;   // 正确:无址引用左值变量p是有址的,转换为有址左值
    cout << "p = " << p << endl;
    int& q = w;
    // static_cast<int&&>(q) = 4;  // 错误:可以转换,但转换后的类型无址,不能对其赋值 
    *const_cast<int*>(&z) = 3;    // 正确:运行无异常,但并不能修改z的值
    *(int*)&z = 3;                  // 正确:运行无异常,但并不能修改z的值
    const_cast<int&>(y) = 4;    // 正确:可以去除全局变量y的volatile属性,::y=4
    
    // 下面的语句会导致程序不执行后面的输出语句
    // 全局const只读变量内存受到保护,下面的语句会引发异常 : 写入位置 0x00007FF75487BDC0 时发生访问冲突。
    // const_cast<int&>(x) = 3;    // 正确:但运行时出现页面保护访问冲突,x仍然是0
    // *const_cast<int*>(&x) = 3;    // 正确:但运行时出现页面保护访问冲突,x仍然是0 
    // *(int*)&x = 3;    // 正确:但运行时出现页面保护访问冲突,x仍然是0  
    cout << "x = " << x << endl;
    cout << "y = " << y << endl;
    cout << "z = " << z << endl;
    return 0;
}

C++-cast系列类型转换示例.jpg C++-cast系列类型转换示例1.jpg C++-cast系列类型转换示例错误.jpg

class Test{
public:
    int number;
    const int nn;
    Test(int m):nn(m){
        number = m;
    }
    void dec()const{
        // number--;       // error: decrement of member ‘Test::number’ in read-only object
        const_cast<Test*>(this)->number--;
        // nn--;           // error: decrement of member ‘Test::nn’ in read-only object
        const_cast<int&>(nn)--;
    }
};

int main()
{
	Test a(7);
	a.dec();
	cout << a.nn << endl;                   // 6
	cout << a.number << endl;               // 6
	const int xx = 0;
	const static int& yy = 0;               // 临时匿名变量,注意与上一句的差别
	volatile int zz = 0;
	int ww = *const_cast<int*>(&xx) = 2;
	cout << xx << endl;                     // 0
	cout << ww << endl;                     // 2
	a.*const_cast<int Test::*>(&Test::nn) = 3;
	cout << a.nn << endl;                   // 3
	const_cast<volatile int&>(yy) = 4;      // 这条语句的执行与编译器有关
	                                        // VS 可以通过,其他的待测试
	                                        // 有些编译器可能这句不会执行,从而导致后面的语句也都不会被执行
	ww = yy;
	cout << yy << endl;						// 4
	cout << ww << endl;						// 4
	const_cast<int&>(zz) = 7;
	//const_cast<const int&>(zz) = 6;
	cout << zz << endl;						// 7
	ww = const_cast<const int&>(zz);
	ww = *const_cast<const int*>(&zz);
	cout << ww << endl;						// 7
	const_cast<volatile int&>(ww) = 5;
	cout << ww << endl;						// 5

	return 0;
}

C++-const_cast示例.jpg

C++-const_cast示例1.jpg

dynamic_cast

  • 检查是否有虚函数

C++-dynamic_cast

struct B{
    virtual B& f(){         // 注意:* 或 & 才能发生协变
        cout << "B\n";
        return *this;
    }
}a, &b = a;
struct D : B{
    D& f()override{
        cout << "D\n";
        return *this;
    }
}c, &d = c;
int main()
{
    D* p1 = static_cast<D*>(&a);
    p1->f();                        // B
    D* p2 = static_cast<D*>(&b);
    p2->f();                        // B
    D* p3 = dynamic_cast<D*>(&a);    // warning: dynamic_cast of ‘B a’ to ‘struct D*’ can never succeed
    cout << p3 << endl;              // 0
    // p3->f();                      
    D* p4 = dynamic_cast<D*>(&b);    // warning: dynamic_cast of ‘B a’ to ‘struct D*’ can never succeed
    cout << p4 << endl;              // 0
    // p4->f();                     
    B* p5 = dynamic_cast<B*>(&c); 
    p5->f();                        // D     
    B* p6 = dynamic_cast<B*>(&d); 
    p6->f();                        // D
    D& r1 = static_cast<D&>(a);     // 语法正确,但不安全的自上向下转换
    r1.f();                         // B
    D& r2 = static_cast<D&>(b);     // 语法正确,但不安全的自上向下转换
    r2.f();                         // B
    // B& r3 = dynamic_cast<D&>(c);    // 语法正确,且为安全的自下向上赋值
    B& r3 = c;
    r3.f();                         // D
    B& r4 = d;    // 语法正确,且为安全的自下向上赋值
    r4.f();                         // D
    B&& rr1 = static_cast<D&&>(c);      // 将子类向上转换为父类的无址引用
    rr1.f();                        // D
    B&& rr2 = dynamic_cast<D&&>(c);
    rr2.f();                        // D
    B&& rr3 = static_cast<D&&>(d);
    rr3.f();                        // D
    B& r5 = dynamic_cast<D&>(rr3);     // 将父类的无址引用转换为子类的有址引用,并赋值给父类的有址引用
    r5.f();                         // D
    
    return 0;
}

reinterpret_cast

C++-reinterpret_cast

C++-reinterpret_cast案例1

C++-reinterpret_cast案例2

C++-reinterpret_cast案例3