当前位置: 首页 > news >正文

jquery网站右侧悬浮返回顶部带双二维码鼠标经过显示全网整合营销推广系统

jquery网站右侧悬浮返回顶部带双二维码鼠标经过显示,全网整合营销推广系统,新兴县城乡建设局网站,网站更新与维护简介 C 类型转换是开发者必须掌握的重要技能之一, 无论是处理隐式转换还是显式转换, 理解其背后的机制与用法至关重要. 本篇博客旨在从基础到高级全面解析 C 的类型转换, 包括实际开发中的应用场景和性能分析. 自动转换 隐式类型转换 编译器可以在无需明确指示的情况下, 将一…

简介

C++ 类型转换是开发者必须掌握的重要技能之一, 无论是处理隐式转换还是显式转换, 理解其背后的机制与用法至关重要. 本篇博客旨在从基础到高级全面解析 C++ 的类型转换, 包括实际开发中的应用场景和性能分析.


自动转换

隐式类型转换

编译器可以在无需明确指示的情况下, 将一种类型的值自动转换为另一种兼容类型. 例如:

struct Struct {Struct(float f) : m_(f) {}float m_ = 0;
};
float f = -3.1415926;
double d = f;
int i = f;
size_t s = f;
char c = f;
Struct st = f;
赋值语句
float f = -3.14;-3.14159
double d = f;-3.14159
int i = f;-3
size_t s = f;18446744073709551613
char c = f;乱码
Struct st = f;{.m_ = -3.14159}

算术类型转换

void drawLine(uint8_t start, uint8_t end);
uint8_t x = 10;
uint8_t width = 50;
// 此处等价于: drawLine(x, static_cast<unsigned char>(static_cast<int>(x) + static_cast<int>(width)));
drawLine(x, x+width);

符号转换

void print(const std::vector<int>& vec) {// 此处等价于: static_cast<unsigned long>(i) < vec.size()for (int i = 0; i < vec.size(); i++) {std::cout << i << ",";}
}

用户转换运算符

class Struct {public:Struct(float f) : m_(f) {}// 重载了转为int类型的操作符operator int() const { return m_; }private:float m_ = 0;
};int main() {Struct si(1);int i = si;
}

显示类型转换

C 风格类型转换

(type)var;
  1. 使用 var 创建 <type> 的临时变量
  2. <type> 可以是任何带有限定符的有效类型
  3. 通过更改变量中位的含义来覆盖类型系统
  4. 在某些情况下无法编译(稍后详细介绍)
  5. 支持在 constexpr 上下文中使用(稍后详细介绍)
  6. 可能导致未定义的行为
  7. 参与运算符优先级(级别 3)
struct A {};
struct B {};int main() {float f = 7.406f;int i = (int)f;             // int i = static_cast<int>(f);A* pa = (A*)&f;             // A* pa = reinterpret_cast<A*>(&f);B* pb = (B*)pa;             // B* pb = reinterpret_cast<B*>(pa);double d = *(double*)(pb);  // double d = *reinterpret_cast<double*>((pb));return 0;
}
C 风格和函数式符号转换的问题
  1. 单一符号, 多重含义
  2. 容易出错
  3. 无法 grep
  4. 使 C 和 C++ 语法复杂化

C++ 强制转换的目标

  1. 不同的符号或不同的任务
  2. 易于识别和搜索
  3. 执行 C 强制转换可以执行的所有操作
  4. 消除意外错误
  5. 使强制转换不那么诱人

C++有如下几种类型转换的关键词:

  1. static_cast
  2. const_cast
  3. dynamic_cast
  4. reinterpret_cast

static_cast

T1 var;
T2 var2 = static_cast<T>(var)
  1. var 类型创建临时变量
  2. 尝试通过隐式和用户定义的转换或构造找到从 T1T2 的路径. 无法删除 const 限定.

使用场景:

  1. 阐明隐式转换

    int i = 1;
    double d = static_cast<double>(i);
    
  2. 指示有意截断

    int a = 1234;
    uint8_t u8 = static_cast<uint8_t>(a);
    
  3. 在基类和派生类之间进行强制转换

    struct Base {};
    struct Derived : public Base {};Derived derived;
    Base& rb = derived;
    Derived& rd = static_cast<Derived&>(rb);
    
  4. void*T* 之间进行强制转换

    struct MyStruct {};
    void callback(void* handle) {auto p = static_cast<MyStruct*>(handle);//...
    }
    
多重转换
#include <cstdio>struct A {explicit A(int) { puts("A"); }
};
struct E {operator int() {puts("B::operator int");return 0;}
};int main() {E e;A a = static_cast<A>(e);return 0;
}
  1. A 有一个接受单个 int 的构造函数
  2. E 有一个用户定义的到 int 的转换
  3. 所以从ea的路径为: e -> int -> a

static_cast 与继承

#include <iostream>struct B1 {virtual ~B1() = default;int i;
};struct B2 {virtual ~B2() = default;int j;
};struct Derived : public B1, public B2 {int k;
};void Compare(void* p1, void* p2) {if (p1 == p2) {std::cout << "Same.\n";} else {std::cout << "Different.\n";}
}int main() {Derived d;// pd 指向派生类Derived* pd = &d;// pb1 是指向基类B1的指针B1* pb1 = static_cast<B1*>(&d);Compare(pd, pb1);  // Same.// pb2 是指向基类B1的指针B2* pb2 = static_cast<B2*>(&d);Compare(pd, pb2);  // Different.void* derived_plus_offset = (char*)pd + sizeof(B1);Compare(derived_plus_offset, pb2);  // Same.return 0;
}

为什么会出现这样的情况? 因为Derived的布局为:

+---------+  <--- pd and pb1
|    B1   |
+---------+  <--- pb2
|    B2   |
+---------+
| Derived |
+---------+...
static_cast 并非绝对正确

static_cast 无法防止向下转型为不相关的类型

#include <iostream>
#include <type_traits>struct Base {virtual void f() { std::cout << "base\n"; }virtual ~Base() = default;
};
struct Derived : public Base {void f() override { std::cout << "Derived\n"; }
};struct Other : public Base {void f() override { std::cout << "Other\n"; }
};int main() {Derived d;Base& b = d;  // OKd.f();  // Derivedb.f();  // DerivedOther& a = static_cast<Other&>(b);  // 危险, 转换到了其他类型a.f();                              // Derivedstatic_assert(std::is_same<decltype(a), Other&>::value, "not the same");return 0;
}

const_cast

  1. 从变量中删除或添加 constvolatile 限定符, 不能更改类型
  2. 不会更改原始变量的 CV 限定符
#include <iostream>void use_pointer(int* p) { std::cout << "*p = " << *p << std::endl; }
void modify_pointer(int* p) {*p = 42;std::cout << "\tmodify_pointer *p <- 42\n"<< "\tmodify_pointer *p = " << *p << std::endl;
}int main() {const int i = 7;use_pointer(const_cast<int*>(&i));modify_pointer(const_cast<int*>(&i));std::cout << "i = " << i << std::endl;  // i = 7int j = 4;const int* cj = &j;modify_pointer(const_cast<int*>(cj));std::cout << "i = " << i << std::endl;  // i = 7return 0;
}

输出

*p = 7modify_pointer *p <- 42modify_pointer *p = 42
i = 7modify_pointer *p <- 42modify_pointer *p = 42
i = 7

可以看到虽然在函数modify_pointer里面指针指向的值发生了变化, 但是在外面的值却不受影响.

const_cast example: member overload

#include <stddef.h>class my_array {public:char& operator[](size_t offset) {// 此处调用const版本的实现, 避免重写一遍逻辑.return const_cast<char&>(const_cast<const my_array&>(*this)[offset]);}const char& operator[](size_t offset) const { return buffer[offset]; }private:char buffer[10];
};
int main() {const my_array a{};const auto& c = a[4];my_array mod_a;mod_a[4] = 7;return 0;
}

用于防止成员函数的代码重复.

运行时类型信息 (RTTI)

  1. 为实现定义的结构中的每个多态类型存储额外信息
  2. 允许在运行时查询类型信息
  3. 可以禁用以节省空间(gcc/clang: –fno-rtti, msvc: /GR-)

dynamic_cast

  1. 查看 To 是否与 From 位于同一公共继承树中
  2. 只能是引用或指针
  3. 不能删除 CV
  4. From 必须是多态的
  5. 需要 RTTI
  6. 如果类型不相关, 则对指针返回 nullptr, 对引用抛出 std::bad_cast
#include <cstdio>
#include <vector>struct A {virtual ~A() = default;
};
struct B : public A {};
struct C : public A {};
int main() {C c;B b;std::vector<A*> a_list = {&c, &b};for (size_t i = 0; i < a_list.size(); ++i) {A* pa = a_list[i];if (dynamic_cast<B*>(pa)) {printf("a_list[%lu] was a B\r\n", i);}if (dynamic_cast<C*>(pa)) {printf("a_list[%lu] was a C\r\n", i);}}return 0;
}

dynamic_cast 用例: UI 框架

struct Widget {};
struct Label : public Widget {};
struct Button : public Widget { void DoClick(); };

dynamic_cast can be expensive

from gcc’s rtti.c

reinterpret_cast

#include <cstdint>struct A {};
struct B {int i;int j;
};int main() {int i = 0;int* pi = &i;uintptr_t uipt = reinterpret_cast<uintptr_t>(pi);float& f = reinterpret_cast<float&>(i);A a;B* pb = reinterpret_cast<B*>(&a);char buff[10];B* b_buff = reinterpret_cast<B*>(buff);return 0;
}
  1. 可以将任何指针或引用类型更改为任何其他指针或引用类型
  2. 也称为类型双关
  3. 不能在 constexpr 上下文中使用
  4. 不能删除 CV 限定
  5. 不确保 To 和 From 的大小相同
  6. 适用于内存映射功能

reinterpret_cast 访问私有继承的基类

struct B {void m() { puts("private to D"); }
};
struct D : private B {};
int main() {D d;B& b = reinterpret_cast<B&>(d);b.m();return 0;
}

Type Aliasing

当两种类型的内存布局兼容时, 将一种类型的内存当作另一种类型的内存来使用的行为.

compatible types

struct Point {int x;int y;
};
struct Location {int x;int y;
};
Point p{1, 2};
auto* loc = reinterpret_cast<Location*>(&p);

incompatible types

float f = 1.0f;
int* i = reinterpret_cast<int*>(&f);

C 风格类型转换在 C++ 中是如何实际执行的

对与一个类型转换

T conv = (T)val;

C++会依次尝试:

  1. T conv = const_cast<T>(val);
  2. T conv = static_cast<T>(val);
  3. T conv = const_cast<T>(static_cast<const T>(val));
  4. T conv = reinterpret_cast<T>(val);
  5. T conv = const_cast<T>(reinterpret_cast<const T>(val));

如果找到匹配则会选择并执行编译, 否则会报错.

总结

C++ 提供了更安全, 更明确的类型转换工具, 开发者应根据场景选择合适的转换方式. 通过熟练掌握这些工具, 您可以编写更健壮, 更易维护的代码. 希望本博客能帮助您更深入地理解 C++ 类型转换的精髓!

参考资源

  • Back to Basics: Casting - Brian Ruth - CppCon 2021

文章转载自:
http://phanerophyte.qpnb.cn
http://estella.qpnb.cn
http://colloidal.qpnb.cn
http://diversiform.qpnb.cn
http://mantle.qpnb.cn
http://condescending.qpnb.cn
http://viewport.qpnb.cn
http://diaphragmatic.qpnb.cn
http://moribund.qpnb.cn
http://foulard.qpnb.cn
http://asocial.qpnb.cn
http://dipterocarp.qpnb.cn
http://optics.qpnb.cn
http://odelsting.qpnb.cn
http://tracheobronchial.qpnb.cn
http://disaccharose.qpnb.cn
http://porphyrise.qpnb.cn
http://haussmannize.qpnb.cn
http://clamor.qpnb.cn
http://trepid.qpnb.cn
http://ayesha.qpnb.cn
http://emoticons.qpnb.cn
http://semihyaline.qpnb.cn
http://tricrotic.qpnb.cn
http://killfile.qpnb.cn
http://calmbelt.qpnb.cn
http://dobeying.qpnb.cn
http://siphunculated.qpnb.cn
http://adaptation.qpnb.cn
http://chaparejos.qpnb.cn
http://onlooking.qpnb.cn
http://enantiopathy.qpnb.cn
http://dewindtite.qpnb.cn
http://lapsible.qpnb.cn
http://mannar.qpnb.cn
http://aerophile.qpnb.cn
http://unconvincing.qpnb.cn
http://encephalolith.qpnb.cn
http://horoscope.qpnb.cn
http://nursekeeper.qpnb.cn
http://lci.qpnb.cn
http://bant.qpnb.cn
http://picaresque.qpnb.cn
http://achene.qpnb.cn
http://towerless.qpnb.cn
http://psychotropic.qpnb.cn
http://crissal.qpnb.cn
http://hepaticotomy.qpnb.cn
http://sportswear.qpnb.cn
http://lueshite.qpnb.cn
http://flask.qpnb.cn
http://sunken.qpnb.cn
http://broth.qpnb.cn
http://stridden.qpnb.cn
http://envenomization.qpnb.cn
http://mecklenburg.qpnb.cn
http://entomologist.qpnb.cn
http://divining.qpnb.cn
http://offish.qpnb.cn
http://bambino.qpnb.cn
http://tridymite.qpnb.cn
http://fratch.qpnb.cn
http://slash.qpnb.cn
http://aeromodelling.qpnb.cn
http://typhogenic.qpnb.cn
http://bloemfontein.qpnb.cn
http://verseman.qpnb.cn
http://intercharacter.qpnb.cn
http://geminorum.qpnb.cn
http://petrochemistry.qpnb.cn
http://orogenics.qpnb.cn
http://smell.qpnb.cn
http://thermometry.qpnb.cn
http://waterproof.qpnb.cn
http://thrustful.qpnb.cn
http://rtl.qpnb.cn
http://iodic.qpnb.cn
http://vigintennial.qpnb.cn
http://fantasy.qpnb.cn
http://charitable.qpnb.cn
http://thespian.qpnb.cn
http://addressable.qpnb.cn
http://samba.qpnb.cn
http://molech.qpnb.cn
http://town.qpnb.cn
http://anglian.qpnb.cn
http://subquadrate.qpnb.cn
http://chagigah.qpnb.cn
http://moonwalk.qpnb.cn
http://cuspidate.qpnb.cn
http://saxboard.qpnb.cn
http://thalloid.qpnb.cn
http://celebrator.qpnb.cn
http://homodesmic.qpnb.cn
http://samnium.qpnb.cn
http://loyalty.qpnb.cn
http://viviparity.qpnb.cn
http://tachinid.qpnb.cn
http://atlanticist.qpnb.cn
http://dmso.qpnb.cn
http://www.hrbkazy.com/news/87130.html

相关文章:

  • brackets做网站教程58网络推广
  • app wordpress类似网站推广优化设计方案
  • jsp做网站用到的软件上海牛巨仁seo
  • 网站开发的形式百度账号购买网站
  • ui设计公司网站微网站
  • weekly做网站百度seo排名
  • 网站的百度快照如何做自己建网站要花多少钱
  • 专业网站制作推广服务外包网络推广
  • 苏州品牌网站建设网络营销的发展概述
  • 动漫设计是干嘛的百度seo排名报价
  • 外贸上哪个网站开发客户下拉关键词排名
  • 国外网站建设现状图分析地推推广方案
  • 盘锦网站建设价位中国十大网站有哪些
  • gulf oil wordpress太原seo管理
  • 网站建设可行性研究报告十大广告投放平台
  • 网站开发工具的功能如何做市场营销推广
  • wordpress搭建影视站广州网站优化排名系统
  • wordpress禁止搜索代码宁波seo排名优化培训
  • asp网站开发环境搭建今日头条新闻军事
  • 营销型企业网站系统模板下载杭州优化外包
  • 贺岁币在建设银行那个网站预约怎么做产品推广和宣传
  • 做wow宏的网站seo优化课程
  • 做响应式网站的框架长尾词排名优化软件
  • 蒙古文政务网站群建设工作方案厦门seo怎么做
  • linux做网站服务器那个软件好百度广告代理商加盟
  • 什么是百度竞价排名seo网站地图
  • 甘肃手机版建站系统哪个好最佳磁力搜索引擎
  • ps做的网站怎样在dw里打开企业网站建站
  • 利用博客做网站江苏网页设计
  • 给境外赌博网站做代理现在推广平台哪家最好