C++类型转换简介

162 阅读3分钟

C++类型转换简介

变量从一种类型到另一种类型的转换被称为类型转换。类型转换的最终目的是使一种数据类型的变量与另一种数据类型的变量一起工作。我们这样做是为了从类型表示和层次结构的某些方面获益。那么,什么时候类型转换会有好处呢?那么,什么时候类型转换会有好处呢?

简介

Type conversions 可以用来强制执行所需的正确的数学计算类型。求两个变量的总和,一个是 类型,另一个是 类型,这是一个很好的int float 例子来证明类型转换的使用。为了得到这两个变量的总和,你必须将 变量转换为 。int float

本文将介绍类型转换,以及实现类型转换的分步演示。

前提条件

要完成这篇文章,你需要具备以下条件。

  • 安装有codeblocks IDE。
  • 对C++语言有一定的了解。

C++类型转换

我们有两种形式的type conversion

  • 隐式类型转换
  • 显式类型转换

让我们开始吧!

隐式类型转换

隐式类型转换也被称为自动类型转换,是由编译器进行的,不需要用户发起的行动。当一个表达式有多个数据类型时,它就会发生,在这种情况下,类型转换会发生,以避免数据丢失。

每个变量的数据类型都被改变为[具有最大数据类型的变量的数据类型]。

自动类型转换的顺序列在下面。

bool -> char -> short int -> int -> 

unsigned int -> long -> unsigned -> 

long long -> float -> double -> long double

当有符号类型被隐含地转换为无符号类型时,符号等信息就会丢失,当long被隐含地转换为float时,将发生溢出。

让我们看一个例子,看看C++中的隐式类型转换是如何工作的。

// C++ program to demonstrate
// Implicit type conversion
#include <iostream>
using namespace std;

int main()
{
  int m = 50; // integer x
  char n = 'x'; // character c

  // n is implicitly converted to int. ASCII
  // value of 'x' is 120
  m = m + n;

  // x is implicitly converted to float
  float a = m + 3.0;

  cout << "m = " << m << endl
    << "n = " << n << endl
    << "a = " << a << endl;

  return 0;
}

继续运行这里的代码。

输出。

m = 170
n = x
a = 173

在上面的程序中,我们可以看到n 被隐式转换为intx 被隐式转换为float ,使用上面列出的自动类型转换顺序。

显式类型转换

显式类型转换也被称为[类型铸造,是由用户发起的]。在显式类型转换中,用户可以通过类型转换[将一种类型的变量转换成另一种数据类型]。

在C++中,显式类型转换可以通过两种方式完成。

  1. 使用cast操作符的转换,和
  2. 使用赋值运算符的转换。

让我们来看看将一种类型显式转换为另一种类型的每一种方式。

使用赋值运算符的转换

在这种类型的转换中,所需的类型是在括号前明确指定的。明确的类型转换会导致数据丢失。它被称为 "强制铸造"。

语法。

(type) expression

Type 表示结果的最终数据类型。

让我们来看一个例子,看看使用赋值运算符的转换是如何进行的。

// C++ program to demonstrate
// explicit type conversion

#include <iostream>
using namespace std;

int main()
{
  double m = 3.0;

  // Explicit conversion from double to int
  int sum = (int)m + 1;

  cout << "Sum = " << sum;

  return 0;
}

继续并运行这里的代码。

输出。

sum = 4

在上面的程序中,我们可以看到显式类型转换是如何发生的。double 被转换为int ,因为用户对结果进行了类型转换。

使用铸型运算符的转换

cast operator 是一个单数运算符,它强制将一种数据类型转换为另一种。我们有四种由c++语言提供的转换类型。

它们是

  1. Static cast - 这是最基本的转换形式。它既可以做上转换,也可以做下转换。这是一种需要很长时间来编译的投射。在整个转换过程中,没有进行检查以确保你所转换的对象是目标类型的完整对象。
  2. Dynamic cast - 它保证类型转换的结果是目标指针类型的一个完整、有效的对象
  3. Const cast - 它确定该对象应该是常数还是非常数。这意味着常量必须被设置或移除。
  4. Reinterpret cast - 每个指针类型都可以被转换为另一个指针类型,即使它们来自不同的类。它并不检查指针所指向的数据和指针类型是否相似。

让我们看一下使用cast操作符的转换是如何进行的。

静态转换

这是可用的最基本形式的转换。它在编译过程中工作。它还可以调用显式转换函数,并进行隐式类型转换,如intfloatpointervoid*

用C++程序来说明静态转换如何工作。

#include <iostream>
using namespace std;
int main()
{
  float m = 6.5;

  // using cast operator
  int n = static_cast<int>(m);

  cout << n;
}

继续并运行这里的代码。

输出。

6

动态转换

多态性是通过这种投射处理的。只有在向派生类投递时才需要使用。这只在继承中从父类到派生类的类型转换时使用。

如果因为指向的对象的实际类型不是期望的子类的类型而导致投递无效,那么动态投递将失败。

我们有两种类型的动态转换。

  1. 指针式动态投掷 如果一个指针被投掷并且失败,那么投掷返回NULL 。这是一个快速而简单的方法来查看一个给定对象是否属于某个动态类型。

语法。

<type> *xsubclass = dynamic_cast<<type> *>( xobject );
  1. 引用动态投掷 在投掷引用时,不可能返回一个NULL指针来表示失败;引用变量的动态投掷会抛出 std::bad cast (来自typeinfo> 头)异常

语法。

<type> subclass = dynamic_cast<<type> &>( ref_obj );

用程序来说明动态投射是如何工作的。

#include<iostream>
using namespace std;
class ClassA {
   public:
      virtual void display()const {
         cout << "This is from ClassA\n";
      }
};
class ClassB {
   public:
      virtual void display()const {
         cout << "This is from ClassB\n";
      }
};
class ClassC: public ClassA, public ClassB {
   public:
      void display()const {
         cout << "This is from ClassC\n";
      }
};
int main(){
   ClassA* x = new ClassA;
   ClassB* y = new ClassB;
   ClassC* z = new ClassC;
   x -> display();
   y -> display();
   z -> display();
   y = dynamic_cast< ClassB*>(x); //This cast will fail
   if (y)
      y->display();
   else
      cout << "No ClassB\n";
   x = z;
   x -> display(); //Displaying from ClassC
   y = dynamic_cast< ClassB*>(x); // There will be Successful casting done here
   if (y)
      y -> display();
   else
      cout << "No Class B\n";
}

输出。

This is from ClassA
This is from ClassB
This is from ClassC
no ClassB
This is from ClassC
This is from ClassC

Const cast

这是用来消除变量的不可变性的。在一个常量成员函数中,非常量类的成员可以通过转换来修改。

用程序来说明const cast是如何工作的。

#include <iostream>
using namespace std;

class employee
{
private:
  int rol;
public:
  // constructor
  employee(int r):rol(r) {}

  // A const function that changes rol with the help of const_cast
  void fun() const
  {
    ( const_cast <employee*> (this) )->rol = 10;
  }

  int getRoll() { return rol; }
};

int main(void)
{
  employee s(5);
  cout << "Old rol no: " << s.getRoll() << endl;

  s.fun();

  cout << "New rol no: " << s.getRoll() << endl;

  return 0;

}

输出。

Old rol no: 5
New rol no: 10

编译器将其视为const 雇员,const this在const成员函数fun() 。这是一个指向常量对象的常量指针,因此,编译器不允许通过这个指针改变数据成员。这个指针的形式被const cast 改为employeeconst this 。

重新解释cast

这个cast是用来将一个类型的指针转换为另一个任何类型的指针的,不管这些类是否有关系。它不检查指针类型和指针指向的数据是否相同。它没有一个返回类型。它只是改变指针的类型。

它只接受一个参数,比如说源指针变量。

// C++ program to illustrate the working of
// reinterpret_cast
#include <iostream>
using namespace std;

int main()
{
  int* m = new int(65);
  char* ch = reinterpret_cast<char*>(m);
  cout << *m << endl;
  cout << *ch << endl;
  cout << m << endl;
  cout << ch << endl;
  return 0;
}

输出。

65
A
0xe2ee70
A

结论

通过使用C++语言提供的类型转换,我们可以很容易地将一个数据类型从一种类型转换成另一种类型。我希望你能发现这篇文章对你作为一个开发者的日常工作有深刻的见解和帮助。