当前位置:   article > 正文

c++ reinterpret_cast类型转换简单实验

c++ reinterpret_cast类型转换简单实验

1.概要

c++提供如下几种转换,具体如下。
static_cast:用于非多态类型的转换。
dynamic_cast:用于多态类型的转换,主要用于向下类型转换(从基类指向派生类的指针/引用),会检查转换的有效性,如果转换不安全,则无法进行转换。
const_cast:用于去除const或volatile属性。
reinterpret_cat:允许所有指针转换为其他指针类型。并允许任何整型转换为任何指针类型反之亦然。

我这里只针对reinterpret_cat的转换进行实验,因为前三种用起来很简单,也很明确,似乎都没有什么明显的价值。
实验结果如下:
基本的结论就是,reinterpret_cat转换就是你如果想转,我就给你转,对象的赋值就是安装内存的面积赋值,其他的我都不管。至于有什么价值,就根据自己需要的场景使用吧,比如无法用面向对象来多态,那么用这个方法也许能起到一些特殊的效果。

2.代码

  1. #include <iostream>
  2. using namespace std;
  3. //名称和变量的转换有什么差别
  4. namespace test1 {
  5. class A
  6. {
  7. public:
  8. int a=0;
  9. void fun() {
  10. cout << "A fun a:" << a << "\n";
  11. }
  12. };
  13. class B
  14. {
  15. public:
  16. int a=1;
  17. void fun() {
  18. cout << "B fun a:" << a << "\n";
  19. }
  20. };
  21. void test() {
  22. cout << "------------------------------------------\n";
  23. A* a = new A();
  24. B* b = reinterpret_cast<B*>(a);
  25. b->fun();
  26. /*
  27. * 执行结果:使用A的变量,使用B的函数
  28. B fun a:0
  29. Hello World!*/
  30. }
  31. }
  32. //不同的变量能否转换成功:可以匹配
  33. namespace test2 {
  34. class A
  35. {
  36. public:
  37. int a = 2;
  38. void fun() {
  39. cout << "A fun a:" << a << "\n";
  40. }
  41. };
  42. class B
  43. {
  44. public:
  45. int b = 1;
  46. void fun() {
  47. cout << "B fun a:" << b << "\n";
  48. }
  49. };
  50. void test() {
  51. cout << "------------------------------------------\n";
  52. A* a = new A();
  53. B* b = reinterpret_cast<B*>(a);
  54. b->fun();
  55. /*
  56. * 执行结果:使用A的变量,使用B的函数
  57. * 虽然变量名,不同了,因为变量只有一个,且类型相同,那么可以匹配
  58. * B fun a:2
  59. */
  60. }
  61. }
  62. //变量类型不同是否匹配:不匹配
  63. namespace test3 {
  64. class A
  65. {
  66. public:
  67. int a = 2;
  68. void fun() {
  69. double d = a;
  70. cout << "A fun a:" << d << "\n";
  71. }
  72. };
  73. class B
  74. {
  75. public:
  76. double b = 1;
  77. void fun() {
  78. cout << "B fun a:" << b << "\n";
  79. }
  80. };
  81. void test() {
  82. cout << "------------------------------------------\n";
  83. A* a = new A();
  84. a->fun();
  85. B* b = reinterpret_cast<B*>(a);
  86. b->fun();
  87. /*
  88. * 结果:
  89. * A fun a:2
  90. * B fun a:-7.84591e+298
  91. * 变量如果类型不同,就无法匹配,但是结果又不像是B类的b(1)
  92. * 那么问题的原因有可能是安装内存的区域拷贝数据了A拷贝给B所以造成B.b不是1
  93. */
  94. }
  95. }
  96. namespace test4 {
  97. class A
  98. {
  99. public:
  100. char a = 1;
  101. char b = 2;
  102. };
  103. class B
  104. {
  105. public:
  106. char b[2] = { 3,4 };
  107. void fun() {
  108. for (size_t i = 0; i < 2; i++)
  109. {
  110. cout << (int)b[i];
  111. }
  112. cout << endl;
  113. }
  114. };
  115. void test() {
  116. cout << "------------------------------------------\n";
  117. A* a = new A();
  118. B b;
  119. b.fun();
  120. try
  121. {
  122. B* b = reinterpret_cast<B*>(a);
  123. b->fun();
  124. }
  125. catch (const std::exception& e)
  126. {
  127. cout << "yichang " << endl;
  128. }
  129. /*
  130. * 结果:
  131. * 34
  132. * 12
  133. * 从结果看,证实了上面的猜测,对象的变量是安装内存拷贝的
  134. * 那也就是从这个使用得到最终的结果:reinterpret_cast类中转换是安装内存的位置匹配的,和变量的名称类型都没有关系。只有内存的位置匹配,就可以安装这个原则拷贝
  135. */
  136. }
  137. }
  138. //试一试A的内存多与B的情况
  139. namespace test5 {
  140. class A
  141. {
  142. public:
  143. int a = 1;
  144. int b = 2;
  145. };
  146. class B
  147. {
  148. public:
  149. int a=3;
  150. void fun() {
  151. cout <<a<< endl;
  152. }
  153. };
  154. void test() {
  155. cout << "------------------------------------------\n";
  156. A* a = new A();
  157. B b;
  158. b.fun();
  159. try
  160. {
  161. B* b = reinterpret_cast<B*>(a);
  162. b->fun();
  163. }
  164. catch (const std::exception& e)
  165. {
  166. cout << "yichang " << endl;
  167. }
  168. /*
  169. * 结果:
  170. * 3
  171. * 1
  172. * 从结果看,B安装自己需要的内存位置有A的内存中获取
  173. */
  174. }
  175. }
  176. namespace test6 {
  177. class A
  178. {
  179. public:
  180. int a = 1;
  181. };
  182. class B
  183. {
  184. public:
  185. int a = 2;
  186. int b = 3;
  187. void fun() {
  188. cout << a << endl;
  189. cout << b << endl;
  190. }
  191. };
  192. void test() {
  193. cout << "------------------------------------------\n";
  194. A* a = new A();
  195. B b;
  196. b.fun();
  197. try
  198. {
  199. B* b = reinterpret_cast<B*>(a);
  200. b->fun();
  201. }
  202. catch (const std::exception& e)
  203. {
  204. cout << "yichang " << endl;
  205. }
  206. /*
  207. * 结果:
  208. * 2
  209. * 3
  210. * 1 //由a获取
  211. * -33686019 //未知的值,不确定是由A获取的,还是默认的初始值。但这部分我认为如果保持B的默认值3应该是更好的
  212. * 从结果看,B安装自己需要的内存位置有A的内存中获取
  213. */
  214. }
  215. }
  216. int main()
  217. {
  218. test1::test();
  219. test2::test();
  220. test3::test();
  221. test4::test();
  222. test5::test();
  223. test6::test();
  224. std::cout << "Hello World!\n";
  225. }

3.运行结果

------------------------------------------
B fun a:0
------------------------------------------
B fun a:2
------------------------------------------
A fun a:2
B fun a:-7.84591e+298
------------------------------------------
34
12
------------------------------------------
3
1
------------------------------------------
2
3
1
-33686019

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/478806
推荐阅读
相关标签
  

闽ICP备14008679号