C++中四种类型转换方式
Qingyh Lv3
- const_cast,去掉(指针或引用)常量属性的一个类型转换,但需要保持转换前后类型一致 - static_cast,提供编译器认为安全的类型转换(最常使用) - reinterpret_cast,类似于c语言风格的强制类型转换,不保证安全; - dynamic_cast,主要用于继承结构中,可以支持RTTI类型识别的(基类到派生类)转换

const_cast

1
2
3
4
5
6
7
8
9
10
11
12
const int a = 10;
//const_cast去掉常量属性,从const int *转换成int *
int* p = const_cast<int *>(&a);
//const_cast去掉常量属性,从const int &转换成int &
int ref = const_cast<int&>(a);

//报错,无法从const int 转换成int,
//const_cast<这里必须是指针类型或引用类型>
int b = const_cast<int> (a);

//const_cast转换前后需要保持类型一致,这里错误,无法从const int *转换成char *
char* p = const_cast<char*>(&a);

static_cast

1
2
3
4
5
6
7
8
9
//static_cast,可以转换编译器认为有联系之间的类型,如(int和char),(基类和派生类)
//int 和 char 都是整数类型,可以安全转换(但可能会发生截断,如果 b 超过 char 的范围
int b = 10;
char c = static_cast<char> (b);

//没有任何联系的两个类型转换,编译器认为是不安全的,不能转换成功
// int* 和 short* 是完全不同的指针类型,它们指向的数据大小不同(int 通常是 4 字节,short 通常是 2 字节)
int *p = nullptr;
short* p1 = static_cast<short> (p);

这里可以转换编译器认为有联系的类型,拒绝不安全的类型转换。

reinterpret_cast转换

1
2
3
4
int* p = nullptr;
//提供c语言风格的强制类型转换,不保证安全,等效于double *p1=(double *) p;
//实际上不安全,double解引用为8个字节,int解引用为4个字节,会造成访问越界
double* p1 = reinterpret_cast<double *> (p);

dynamic_cast转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Animal {
public:
virtual void bark() = 0; // 必须要有虚函数(多态类型)
};

class Dog : public Animal {
public:
void bark() { cout << "Dog Woof! Woof!" << endl; }
};

class Cat : public Animal {
public:
void bark() { cout << "Cat Meow! Meow!" << endl; }
};

void showAnimal(Animal* animal) {
animal->bark();
}

int main() {
Dog dog;
Cat cat;

showAnimal(&dog);
showAnimal(&cat);

return 0;
}

这里通过的showAnimal函数通过基类指针指向不同的派生类,从而实现调用其对应的重写方法。
但是比如说,对于Dog类,我想调用实现其另一个eat方法。

1
2
3
4
5
6
class Dog : public Animal {
public:
void bark() { cout << "Dog Woof! Woof!" << endl; }
//新增eat方法
void eat() { cout << "Dog like eat bone!"<<endl; }
};

当调用showAnimal方法时,如果其指向的时Dog方法,就调用eat方法,就可以通过dynamic_cast实现,如代码所示

1
2
3
4
5
6
7
8
9
10
11
void showAnimal(Animal* animal) {
Dog* dog = static_cast<Dog*>(animal); // 尝试转换为 Dog*
if (dog) {
dog->eat();
}
else
{
animal->bark();
}

}

dynamic_cast<Dog*>(animal) 会检查 animal 是否真的指向 Dog 对象:

  • 如果是,返回 Dog*;
  • 如果不是,返回 nullptr(而不是崩溃或未定义行为)

image

我们之前也说了static_cast也可以进行基类和派生类的转换,但是这里是不会判断直接进行转换的,不管基类指针是不是指向Dog的派生类,都一律被转换成Dog的派生类;而dynamic_cast会进行判断,只有基类指针指向的是Dog类型的派生类时,才发生转换,否则返回nullptr。

image

最后,目前就先总结这些,后续项目中遇到了再添加内容。

$share-item-width = 1.8rem .post-share-container { flex-shrink 0 .share-list-wrap { display flex justify-content flex-end .share-item { width $share-item-width height $share-item-width margin-left 0.5rem padding 0.4rem border-style solid border-width 0.1rem border-radius 50% cursor pointer transition-t("background", "0", "0.3", "ease") i { color inherit font-size 1rem } &.qq { color var(--keep-primary-color) border-color var(--keep-primary-color) &:hover { color var(--background-color-1) background var(--keep-primary-color) } } &.wechat { color var(--keep-success-color) border-color var(--keep-success-color) img { filter brightness(1) !important &[lazyload] { &::before { background #fff !important } } } &:hover { color var(--background-color-1) background var(--keep-success-color) } } &.weibo { color var(--keep-danger-color) border-color var(--keep-danger-color) &:hover { color var(--background-color-1) background var(--keep-danger-color) } } } } }
if (hexo-config('comment') && hexo-config('comment.enable') == true && hexo-config('comment.use')) { if (hexo-config('comment.use') == "valine") { @import "./valine.styl" } else if (hexo-config('comment.use') == "gitalk") { @import "./gitalk.styl" } else if (hexo-config('comment.use') == "twikoo") { @import "./twikoo.styl" } else if (hexo-config('comment.use') == "waline") { @import "./waline.styl" } } .comments-container { display inline-block width 100% margin-top var(--component-gap) .comment-area-title { width 100% color var(--text-color-3) font-size 1.38rem line-height 2 i { color var(--text-color-3) } +keep-tablet() { font-size 1.2rem } } .configuration-items-error-tip { display flex align-items center margin-top 1rem color var(--text-color-3) font-size 1rem i { margin-right 0.3rem color var(--text-color-3) font-size 1.2rem } } .comment-plugin-fail { display none flex-direction column align-items center justify-content space-around width 100% padding 2rem .fail-tip { color var(--text-color-3) font-size 1.1rem } .reload { margin-top 1rem } } .comment-plugin-loading { flex-direction column padding 1rem color var(--text-color-3) .loading-icon { color var(--text-color-4) font-size 2rem } .load-tip { margin-top 1rem color var(--text-color-4) font-size 1.1rem } } }
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 42.9k
$li-margin-bottom = 0.8rem $post-tool-button-width = 2.5rem .post-tools-container { padding-top var(--component-gap) .post-tools-list { li { margin-bottom $li-margin-bottom &:last-child { margin-bottom 0 } } li.tools-item { position relative box-sizing border-box width $post-tool-button-width height $post-tool-button-width color var(--text-color-3) font-size 1.2rem background var(--background-color-1) border-radius 50% box-shadow 2px 2px 5px var(--shadow-color) cursor pointer &:hover { box-shadow 2px 2px 8px var(--shadow-hover-color) } i { color var(--text-color-3) } &:hover { color var(--background-color-1) background var(--primary-color) i { color var(--background-color-1) !important } } &.toggle-show-toc { display none } &.go-to-comments { .post-comments-count { position absolute top 0 right -1rem display none align-items center justify-content center box-sizing border-box min-width 1.1rem height 1.1rem padding 0 0.2rem color var(--badge-color) font-size 12px background var(--badge-background-color) border-radius 0.4rem +keep-tablet() { display none !important } } } } li.status-item { width $post-tool-button-width height $post-tool-button-width color var(--text-color-3) font-size 1.6rem cursor pointer &.post-lock { cursor default .fa-lock-open { display none color var(--keep-success-color) } &.decrypt { cursor pointer .fa-lock-open { display block } .fa-lock { display none } } } } } }