C++11关键字~const_cast、static_cast、dynamic_cast、reinterpret_cast

目录

1 reinterpret_cast 

2 const_cast

3 static_cast 

4 dynamic_cast

5 dynamic_cast 和 static_cast 区别


        加上 c like cast 其实共5种方式进行类型转化,名字过于冗长,意思为尽量少用,但是也有不得不用的场景,所以进行整理 

1 reinterpret_cast 

即reinterpret_cast运算符允许将任意指针转换到其他指针类型,也允许做任意整数类型和任意指针类型之间的转换。转换时,执行的是逐个比特复制的操作。reinterpret中文意为“重新解释; 重新诠释;

void testReinterpret() {
    //同时也是一个判断大小端的例子
	int a = 1;
	auto p = reinterpret_cast<char*>(&a);
	if(p[0] == 1) std::cout << "the system is little endian\n";
	else std::cout << "the system is big endian\n";
    
    // C like cast
	auto pp = (char*)(&a);
	
    
	int c = 100;
	auto cc = static_cast<char>(c);
	auto ccc = (char)c;
}

2 const_cast

struct A{};

void testConstCast() {
    const int j = 3; // j is declared const
    int* pj = const_cast<int*>(&j);
    //结构体或类的转换
    const A a;
    auto p = const_cast<A*>(&a);
    // C like cast
    auto c = (A*)(&a);
}

void testA(const int& a) {}
void testB(const int& b) {}
void testConstCast2() {
    const int j = 3; // j is declared const
	std::thread aa([&j]{testA(j);});
	std::thread bb([&j]{testB(j);});
	//const int*
	int* pj = const_cast<int*>(&j);
	*pj = 4;         // undefined behavior!
}

testConstCast2转换了指针会有未定义的行为,虽然例子比较牵强;

3 static_cast 

struct A {
  A(int) {}
  A(int, int) {}
  operator int() const { return 0; }
};

struct B {
  explicit B(int) {}
  explicit B(int, int) {}
  explicit operator int() const { return 0; }
};

void testExpl() {
    A a1 = 1; // A a1 = A(1);
    // B b1 = 1; // ERROR
    A a2(2);
    B b2(2); // OK
    A a3 = {4, 5}; // A a3 = A(4,5); A{4,5};
    //B b3 = {4,5}; //  ERROR
    int na1 = a1; // OK
    //int nb1 = b2; // ERROR
    int na2 = static_cast<int>(a1);
    int nb2 = static_cast<int>(b2);
    
    // C like cast
    A a4 = (A)1;
    B b4 = (B)1;
}

4 dynamic_cast

        运行期间会做检查

struct Base{
    virtual ~Base(){}
};

struct Derived : Base {
  virtual void name() {}
};

void testDyn() {
  Base *b1 = new Base;
  if (Derived *d = dynamic_cast<Derived *>(b1)) {
    std::cout << "downcast from b1 to d successful\n";
    d->name(); // safe to call
  }
  Base *b2 = new Derived;
  if (Derived *d = dynamic_cast<Derived *>(b2)) {
    std::cout << "downcast from b2 to d successful\n";
    d->name(); // safe to call
  }
  
//引用抛出异常,因为引用必须有指向物,所以抛出异常
    Base bb;
    Derived& cc = dynamic_cast<Derived&>(bb);
}

5 dynamic_cast 和 static_cast 区别

class Base {
	public:
		virtual ~Base() {}// why? virtual
		virtual void act(Event const&) = 0;
		virtual void print() const = 0;
		int id() const { return m_id;}
		virtual void update() {}
		Base(int _id) : m_id(_id) {}
		virtual void addBase(Base* b) {}
		virtual void removeBase(int id) {}
	private:
		int m_id;
};

class Drived : public Base { // why public
	public:
		void act(Event const&);
		void print() const;
		Drived(int id);
		~Drived();
	private:
};

class Grouped : public Base {
public:
  void act(Event const &);
  void print() const;
	void addBase(Base* b);
	void removeBase(int id);
	Grouped(int id);
	~Grouped();
private:
  std::map<int, Base *> m_info;
};
int main() {

    Drived* info = new Drived(1);
	Grouped* group = new Grouped(2);
    // 这种情况下均可以	
    Base* baseGroup = group;
    Grouped* g = static_cast<Grouped*>(baseGroup);
    Grouped* g2 = dynamic_cast<Grouped*>(baseGroup);
    Grouped* g2 = (Grouped*)(baseGroup);

     // 这种情况下需要慎重考虑	
    Base* baseGroup2 = info;
    Grouped* g = static_cast<Grouped*>(baseGroup);
    g->removeBase(info) // 这种情况直接出错,导致程序崩掉或dump,总之莫名其妙
    Grouped* g2 = dynamic_cast<Grouped*>(baseGroup); // 此种情况会判断,是否能转换;
     // 如不能 ,会返回一个空指针(nullptr) ,所以你可以做检查
    if(g2){}
    else {}
    
    Grouped* g3 = (Grouped*)(baseGroup);  // 也会强转,但是会导致行为不正确;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值