在将varchar值id转换为int时失败_C++繁琐的类型转换,C++小知识之四种类型转换

3ccc4f73b201616a32ca1c4059da6340.png

有时,编程的过程中需要将值从一种数据类型转换为另一种数据类型。

在C语言中,强制类型转换的方式为(Type)Expression,另外还有一种现在已经不用的旧式写法Type(Expression),这两种方式是等价的。

但是,C语言的强制类型转换方式存在一些问题:过于粗暴,可以在任意类型之间进行转换,编译器很难判断其正确性,难于定位,在源代码中无法快速定位所有使用强制类型转换的语句。

然而,强制类型转换在实际工程中几乎是不可避免的,为此C++将强制类型转换分为4种不同的类型,以提供更加安全可靠的转换。

static_cast

用法:static_cast (expression)

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

(1)用于类层次结构中基类和派生类之间指针或引用的转换。

进行上行转换(把派生类的指针或引用转换成基类表示)是安全的

进行下行转换(把基类的指针或引用转换为派生类表示),由于没有动态类型检查,所以是不安全的

(2)用于基本数据类型之间的转换,如把int转换成char。这种转换的安全也要开发人员来保证

(3)把空指针转换成目标类型的空指针

(4)把任何类型的表达式转换为void类型

注意:static_cast不能转换掉expression的const、volitale或者__unaligned属性。主要用于基本类型之间、有继承关系的类对象之间、类指针之间的转换,不能用于基本类型指针之间的转换。

比如:下面代码第五行会报错,“static_cast”: 无法从“float *”转换为“int *”

bad934c011bdefb11fa7518d98a4e741.png

const_cast

用法:const_cast (expression)

该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。

常量指针被转化成非常量指针,并且仍然指向原来的对象;

常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

注意:用于去除变量的只读属性,强制转换的目标类型必须是指针或引用

比如:下面代码第二行会报错,“const_cast”: 无法从“const int”转换为“int”,值得注意的是,强转去掉常量属性之后通过指针修改变量,并不能改变原本常量的值,在【C++const常量玩出新花样】中有讲到

90fd5db174e4637af70fb6ada8b76c81.png

结果:

8dfb7d2ca5897c98029526920c7173f8.png

reinterpret_cast

用法:reinterpret_cast (expression)

它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。

该运算符的用法比较多。

该运算符平台移植性比价差。

注意:type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。用于指针类型之间、整数和指针类型之间的转换

比如:下面代码第三行会报错,“reinterpret_cast”: 无法从“float”转换为“int”。

85e475fce61ab67c5081ae34d931f0d5.png

dynamic_cast

用法:dynamic_cast (expression)该运算符把expression转换成type_id类型的对象。type_id必须是类的指针、引用或者void*;如果type_id是类指针类型,那么expression也必须是一个指针,如果type_id是一个引用,那么expression也必须是一个引用。 dynamic_cast主要用于有继承关系的类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;

在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

#include using namespace std;class parent{public:virtual void print(){cout << "parent" << endl;}};class son :public parent{public: void print(){cout << "son" << endl; } void printData() { cout << "printData" << endl; }};int main(){parent* ppParent = new son;  //调用是子类中与virtual 的同名函数ppParent->print();//调用是子类中与virtual 的同名函数son* ppSon = nullptr;if ((ppSon = dynamic_cast(ppParent)) != nullptr){ppSon->print(); ppSon->printData();}else{cout << "转换失败" << endl;}system("pause");return 0;}

尾言

如果足下基础比较差,不妨关注下人人都可以学习的视频教程通俗易懂,深入浅出,一个视频只讲一个知识点。视频不深奥,不需要钻研,在公交、在地铁、在厕所都可以观看,随时随地涨姿势的视频教程

你可以使用sqlite3_column_text()函数来获取varchar类型的,并将其转换为C字符串。然后,你可以使用C++的std::string类来保存这个C字符串。 以下是一个示例代码,用于从SQLite3数据库中读取varchar类型的并将其保存到std::string变量中: ```c++ #include <iostream> #include <sqlite3.h> #include <string> using namespace std; int main() { sqlite3 *db; sqlite3_stmt *stmt; int rc = sqlite3_open("example.db", &db); if (rc) { cerr << "Can't open database: " << sqlite3_errmsg(db) << endl; sqlite3_close(db); return 1; } rc = sqlite3_prepare_v2(db, "SELECT name FROM users WHERE id = ?", -1, &stmt, NULL); if (rc != SQLITE_OK) { cerr << "Can't prepare statement: " << sqlite3_errmsg(db) << endl; sqlite3_close(db); return 1; } int id = 1; sqlite3_bind_int(stmt, 1, id); rc = sqlite3_step(stmt); if (rc == SQLITE_ROW) { const char *name_cstr = (const char*)sqlite3_column_text(stmt, 0); string name(name_cstr); cout << "Name: " << name << endl; } else if (rc == SQLITE_DONE) { cerr << "No data found." << endl; } else { cerr << "Error fetching data: " << sqlite3_errmsg(db) << endl; } sqlite3_finalize(stmt); sqlite3_close(db); return 0; } ``` 在此示例中,我们从名为“users”的表中选择名为“name”的列,并使用id = 1的条件进行过滤。我们使用sqlite3_column_text()函数获取varchar类型的,并将其转换为C字符串。然后,我们将C字符串传递给std::string构造函数以创建一个std::string对象。最后,我们使用std::cout输出字符串的。 请注意,此代码假定SQLite3数据库中的“name”列是varchar类型。如果该列是其他类型(例如整数或浮点数),则你需要使用相应的sqlite3_column_*()函数来获取该,并将其转换为适当的C++类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值