面向对象进阶--转换构造函数,重载,类型转换函数

转换构造函数

1.将其他类型转换为当前类类型需要借助转换构造函数。

具体看例子:点击

类型转换函数

1.将当前类类型转换为其他类型,只能出现在类中。

2.语法格式:

operator type(){
    //TODO:
    return data;
}

operator 是 C++ 关键字,type 是要转换的目标类型,data 是要返回的 type 类型的数据。

具体点击

再谈转换构造函数和类型转换函数(例子)

具体点击

类型转换的本质

具体点击

四种类型转换运算符

static_cast     dynamic_cast      const _cast和reinterpret_cast

关键字 说明
static_cast 用于良性转换,一般不会导致意外发生,风险很低。
const_cast 用于 const 与非 const、volatile 与非 volatile 之间的转换。
reinterpret_cast 高度危险的转换,这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但是可以实现最灵活的 C++ 类型转换。
dynamic_cast 借助 RTTI,用于类型安全的向下转型(Downcasting)。

static_cast关键字

1.static_cast 只能用于良性转换,这样的转换风险较低,一般不会发生什么意外,例如:

  • 原有的自动类型转换,例如 short 转 int、int 转 double、const 转非 const、向上转型等;
  • void 指针和具体类型指针之间的转换,例如void *int *char *void *等;
  • 有转换构造函数或者类型转换函数的类与其它类型之间的转换,例如 double 转 Complex(调用转换构造函数)、Complex 转 double(调用类型转换函数)。

需要注意的是,static_cast 不能用于无关类型之间的转换,因为这些转换都是有风险的,例如:

  • 两个具体类型指针之间的转换,例如int *double *Student *int *等。不同类型的数据存储格式不一样,长度也不一样,用
    A 类型的指针指向 B 类型的数据后,会按照 A 类型的方式来处理数据:如果是读取操作,可能会得到一堆没有意义的值;如果是写入操作,可能会使 B
    类型的数据遭到破坏,当再次以 B 类型的方式读取数据时会得到一堆没有意义的值。
  • int 和指针之间的转换。将一个具体的地址赋值给指针变量是非常危险的,因为该地址上的内存可能没有分配,也可能没有读写权限,恰好是可用内存反而是小概率事件。

 1 #include <iostream>
 2 #include <cstdlib>
 3 using namespace std;
 4
 5 class Complex{
 6 public:
 7     Complex(double real = 0.0, double imag = 0.0): m_real(real), m_imag(imag){ }
 8 public:
 9     operator double() const { return m_real; }  //类型转换函数
10 private:
11     double m_real;
12     double m_imag;
13 };
14
15 int main(){
16     //下面是正确的用法
17     int m = 100;
18     Complex c(12.5, 23.8);
19     long n = static_cast<long>(m);  //宽转换,没有信息丢失
20     char ch = static_cast<char>(m);  //窄转换,可能会丢失信息
21     int *p1 = static_cast<int*>( malloc(10 * sizeof(int)) );  //将void指针转换为具体类型指针
22     void *p2 = static_cast<void*>(p1);  //将具体类型指针,转换为void指针
23     double real= static_cast<double>(c);  //调用类型转换函数
24
25     //下面的用法是错误的
26     float *p3 = static_cast<float*>(p1);  //不能在两个具体类型的指针之间进行转换
27     p3 = static_cast<float*>(0X2DF9);  //不能将整数转换为指针类型
28
29     return 0;
30 }

const_cast关键字

将const类型转换为非const类型

 1 #include <iostream>
 2 using namespace std;
 3
 4 int main(){
 5     const int n = 100;
 6     int *p = const_cast<int*>(&n);
 7     *p = 234;
 8     cout<<"n = "<<n<<endl;
 9     cout<<"*p = "<<*p<<endl;
10
11     return 0;
12 }

运行结果:

n = 100;

*p = 234;

&n用来获取 n 的地址,它的类型为const int *,必须使用 const_cast 转换为int *类型后才能赋值给 p。由于 p 指向了 n,并且 n 占用的是栈内存,有写入权限,所以可以通过 p 修改 n 的值。

有读者可能会问,为什么通过 n 和 *p 输出的值不一样呢?这是因为 C++ 对常量的处理更像是编译时期的#define,是一个值替换的过程,代码中所有使用 n 的地方在编译期间就被替换成了 100。换句话说,第 8 行代码被修改成了下面的形式:

cout<<"n = "<<100<<endl;

reinterpret_cast关键字

 1 #include <iostream>
 2 using namespace std;
 3
 4 class A{
 5 public:
 6     A(int a = 0, int b = 0): m_a(a), m_b(b){}
 7 private:
 8     int m_a;
 9     int m_b;
10 };
11
12 int main(){
13     //将 char* 转换为 float*
14     char str[]="http://c.biancheng.net";
15     float *p1 = reinterpret_cast<float*>(str);
16     cout<<*p1<<endl;
17     //将 int 转换为 int*
18     int *p = reinterpret_cast<int*>(100);
19     //将 A* 转换为 int*
20     p = reinterpret_cast<int*>(new A(25, 96));
21     cout<<*p<<endl;
22
23     return 0;
24 }

dynamic_cast关键字

dynamic_用于类的继承层次进行类型转换,允许向上转型,也允许向下转型。向上转型无检测,向下转型需经rtti进行检测,只有部分成功。

语法格式:

dynamic_cast<newType>(rxpression)

newType 和 expression 必须同时是指针类型或者引用类型。换句话说,dynamic_cast 只能转换指针类型和引用类型,其它类型(int、

double、数组、类、结构体等)都不行。

向上转型与向下转型

原文地址:https://www.cnblogs.com/Mayfly-nymph/p/8974623.html

时间: 2024-10-09 03:03:42

面向对象进阶--转换构造函数,重载,类型转换函数的相关文章

C++语言基础(22)-转换构造函数和类型转换函数

一.转换构造函数 将其它类型转换为当前类类型需要借助转换构造函数(Conversion constructor).转换构造函数也是一种构造函数,它遵循构造函数的一般规则.转换构造函数只有一个参数. #include <iostream> using namespace std; //复数类 class Complex{ public: Complex(): m_real(0.0), m_imag(0.0){ } Complex(double real, double imag): m_real

c++转换构造函数和类型转换函数

看stl源码时,有一段代码感觉很奇怪 iterator begin() { return (link_type)((*node).next); } iterator和link_type是两种不同类型,怎么能这么返回呢?翻了一下以前的笔记,发现是由转换构造函数生成临时对象再return. 转换构造函数的作用是将某种类型的数据转换为类的对象,当一个构造函数只有一个参数,而且该参数又不是本类的const引用时,这种构造函数称为转换构造函数.试验了一下 class A { public: int a;

C++ Primer 学习笔记_29_操作符重载与转换(4)--转换构造函数和类型转换运算符归纳、operator new 和 operator delete 实现一个简单内存泄漏跟踪器

C++ Primer 学习笔记_29_操作符重载与转换(4)--转换构造函数和类型转换运算符归纳.operator new 和 operator delete 实现一个简单内存泄漏跟踪器 一.转换构造函数 可以用单个实参来调用的构造函数定义从形参类型到该类型的一个隐式转换.如下: class Integral { public: Integral (int = 0); //转换构造函数 private: int real; }; Integral A = 1; //调用转换构造函数将1转换为In

effective c++条款13-17 “以对象管理资源”之C++隐式转换和转换构造函数

其实我们已经在C/C++中见到过多次标准类型数据间的转换方式了,这种形式用于在程序中将一种指定的数据转换成另一指定的类型,也即是强制转换,比如:int a = int(1.23),其作用是将1.23转换为整形1.然而对于用户自定义的类类型,编译系统并不知道如何进行转换,所以需要定义专门的函数来告诉编译系统改如何转换,这就是转换构造函数和类型转换函数! 注意:转换构造函数.隐式转换和函数对象不要搞混淆!!!函数对象是重载运算符(),和隐式转换函数易混淆. 一.转换构造函数 转换构造函数(conve

C++中的类型转换函数

1,转换构造函数可以将普通的基础类型转换为当前的类类型,也有能力将其它类类 型的对象转换为当前的类类型: 2,问题: 1,类类型是否能够类型转换到普通类型? 1,可以的: 3,类型转换函数: 1,C++ 类中可以定义类型转换函数: 2,类型转换函数用于将类对象转换为其他类型: 1,不管什么类型都可以: 3,语法规则: 1,代码示例: 1 operator Type () // operator 表示定义类型转换函数,Type 表示返回值,没有参数: 2 { // 函数体表示普通的函数体内容: 3

C++类转换构造函数和转换函数复习

//C++类转换构造函数和转换函数复习 #include<iostream> #include<string> using namespace std; class Student { private: string name; int age; double grade; public: Student(string name_, int age_, double grade_):name(name_), age(age_), grade(grade_){} Student(){

C++ Primer 学习笔记_86_模板与泛型编程 --重载与函数模板

模板与泛型编程 --重载与函数模板 引言: 函数模板可以重载:可以定义有相同名字但参数数目或类型不同的多个函数模板,也可以定义与函数模板有相同名字的普通非模板函数. 但是,声明一组重载函数模板不保证可以成功调用它们,重载的函数模板可能会导致二义性. 一.函数匹配与函数模板 如果重载函数中既有普通函数又有函数模板,确定函数调用的步骤如下: 1.为这个函数名建立候选函数集合,包括: a.与被调用函数名字相同的任意普通函数. b.任意函数模板实例化,在其中,模板实参推断发现了与调用中所用函数实参相匹配

21.C++- ++操作符重载、隐式转换之explicit关键字、类的类型转换函数

++操作符重载 ++操作符分为前置++和后置++,比如: ++a;  a++; ++操作符可以进行全局函数或成员函数重载 重载前置++操作符不需要参数 重载后置++操作符需要一个int类型的占位参数 前置++操作符的返回值为*this 后置++操作符的返回值为临时对象 例如: 转换规则如下所示: 比如: 隐式转换的隐患 隐式转换有时会因为类型不同,得到的结果大有不同,也是常见bug之一. 参考以下示例: 运行打印: 答案并非是-1000. 同样,我们使用构造函数时,也经常使用隐式转换 参考以下示

C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象

重载操作符与转换 --调用操作符和函数对象 引言: 能够为类类型的对象重载函数调用操作符:一般为表示操作的类重载调用操作符! struct absInt { int operator() (int val) { return val > 0 ? val : -val; } }; 通过为类类型的对象提供一个实參表而使用调用操作符,所用的方式看起来系那个一个函数调用: absInt absObj; int i = -1; cout << absObj(i) << endl; 虽然