在C++中有着各种类型转换,其中包括:
对于隐式类型转换,其中存在小问题,例如:
c++float f = 10.f;
int i = f;
当我们在几千行代码中看到了第二句,我们的第一印象可能会是f本身就是int类型,当我们之后以 int 类型使用 f 时,问题就来了,这是很糟糕的。
因此,我们更应该使用C++特有的四种强制类型转换。
static_cast为静态类型转换,它可以进行基本内置类型之间的转换
c++// static_cast 2.
float f = 10.f;
int i = static_cast<int>(f);
同时,他还可以通过 void* 来进行任意指针类型之间的转换
c++// static_cast 2.
A a;
void *vap = static_cast<void *>(&a);
int *ip = static_cast<int *>(vap);
std::cout << "*ip: " << *ip << std::endl;
当进行类之间的转换时(存在继承关系),如果没有多态,只支持上行。存在多态,也只支持上行,但无法继续完成多态
C++// static_cast 3.
CA ca;
A a_ = static_cast<A>(ca); // 上行ok
a_.funcA();
// CA ca_ = static_cast<CA>(a); // 下行报错
// static_cast 4.
Base base;
Derived derived;
Base _base = static_cast<Base>(derived); // 上行ok,但是没有多态
_base.func();
// Derived _derived = static_cast<Derived>(base);// 下行报错
当进行的是类指针之间的转换时(存在继承关系),如果没有多态,那都支持,但下行不安全。存在多态,都支持,但某些下行不安全
C++// static_cast 5.
CA *ca_ = static_cast<CA *>(&a);
ca_->funcCA(); // 下行不安全
CA &car_ = static_cast<CA &>(a);
car_.funcCA(); // 下行不安全
// static_cast 6.
Base *_baseptr = static_cast<Base *>(&derived); // 上行ok,多态
_baseptr->func();
Derived *_derivedptr = static_cast<Derived *>(&base); // 下行不安全
_derivedptr->func();
Derived *_derivedptr_ = static_cast<Derived *>(_baseptr); // 下行安全
_derivedptr_->func();
因此对于静态类型转换,可以满足我们的大多数需求,在转换的同时为我们指明了转换的目的和意图,可以帮助我们更好的完成代码工作。
将基类类型的指针或引用安全的转换为派生类的指针或引用
c++// dynamic_cast
Base *_baseptr_d = dynamic_cast<Base *>(&derived); // 上行ok,多态
_baseptr_d->func();
Derived *_derivedptr_d = dynamic_cast<Derived *>(&base); // 下行不安全
if (_derivedptr_d) {
_derivedptr_d->func();
}
Derived *_derivedptr__d = dynamic_cast<Derived *>(_baseptr); // 下行安全
_derivedptr__d->func();
去除const 或 添加const
c++// const_cast
const char *pc = "hello world";
// char *p = pc;
char *p = const_cast<char *>(pc);
// p[2] = 'a'; // 段错误
std::string aas = "hello";
std::string bbs = "ll";
shorterString(aas, bbs);
const std::string& shorterString(const std::string &s1,
const std::string &s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
std::string& shorterString(std::string &s1,
std::string &s2)
{
auto &r = shorterString(const_cast<const std::string &>(s1),
const_cast<const std::string &>(s2));
// return r;
return const_cast<std::string &>(r);
}
为运算对象的位模式提供低层次上的重新解释
c++// reinterpred_cast 1.
int *i_ = reinterpret_cast<int *>(i);
int64_t cpi = reinterpret_cast<int64_t>(pc);
// reinterpred_cast 2.
int *vap_ = reinterpret_cast<int *>(&a);
c++#include <iostream>
#include <string>
struct A
{
int a{20};
void funcA() { std::cout << "A::funA" << std::endl; }
};
struct B
{
int b{};
void funcB() { std::cout << "B::funB" << std::endl; }
};
struct CA : public A
{
int c{25};
void funcCA()
{
std::cout << "c is: " << c << std::endl;
std::cout << "CA::funcCA" << std::endl;
}
};
struct Base
{
virtual void func()
{
std::cout << "Base::func()" << std::endl;
}
};
struct Derived : public Base
{
virtual void func() override
{
std::cout << "Derived::func()" << std::endl;
}
};
const std::string &shorterString(const std::string &s1,
const std::string &s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
std::string &shorterString(std::string &s1,
std::string &s2)
{
auto &r = shorterString(const_cast<const std::string &>(s1),
const_cast<const std::string &>(s2));
// return r;
return const_cast<std::string &>(r);
}
int main()
{
// static_cast 1.
float f = 10.f;
int i = static_cast<int>(f);
// static_cast 2.
A a;
void *vap = static_cast<void *>(&a);
int *ip = static_cast<int *>(vap);
std::cout << "*ip: " << *ip << std::endl;
// static_cast 3.
CA ca;
A a_ = static_cast<A>(ca); // 上行ok
a_.funcA();
// CA ca_ = static_cast<CA>(a); // 下行报错
// static_cast 4.
Base base;
Derived derived;
Base _base = static_cast<Base>(derived); // 上行ok,但是没有多态
_base.func();
// Derived _derived = static_cast<Derived>(base);// 下行报错
// static_cast 5.
CA *ca_ = static_cast<CA *>(&a);
ca_->funcCA(); // 下行不安全
CA &car_ = static_cast<CA &>(a);
car_.funcCA(); // 下行不安全
// static_cast 6.
Base *_baseptr = static_cast<Base *>(&derived); // 上行ok,多态
_baseptr->func();
Derived *_derivedptr = static_cast<Derived *>(&base); // 下行不安全
_derivedptr->func();
Derived *_derivedptr_ = static_cast<Derived *>(_baseptr); // 下行安全
_derivedptr_->func();
// dynamic_cast
Base *_baseptr_d = dynamic_cast<Base *>(&derived); // 上行ok,多态
_baseptr_d->func();
Derived *_derivedptr_d = dynamic_cast<Derived *>(&base); // 下行不安全
if (_derivedptr_d)
{
_derivedptr_d->func();
}
Derived *_derivedptr__d = dynamic_cast<Derived *>(_baseptr); // 下行安全
_derivedptr__d->func();
// const_cast
const char *pc = "hello world";
// char *p = pc;
char *p = const_cast<char *>(pc);
// p[2] = 'a'; // 段错误
std::string aas = "hello";
std::string bbs = "ll";
shorterString(aas, bbs);
// reinterpred_cast 1.
int *i_ = reinterpret_cast<int *>(i);
int64_t cpi = reinterpret_cast<int64_t>(pc);
// reinterpred_cast 2.
int *vap_ = reinterpret_cast<int *>(&a);
return 0;
}
本文作者:流浪的将军
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!