reinterpret_cast<> 理解以及典型应用[cpp][类型转换]

本文探讨了如何使用ffmpeg进行视频帧解码,并详细介绍了reinterpret_cast的用法,包括其在模板函数中的应用,以及它如何处理不同类型对象内存布局。通过实例展示了静态_cast和reinterpret_cast的区别,重点在于理解指针如何视作不同类型的对象。

1 ffmpeg 解帧

ffmpeg -i DJI_20210615164633_0003_W.MP4 -r 3 images/%4d.jpg

2 reinterpret_cast<> 理解以及典型应用:

对于其他的例如static_cast<>等的应用,参考:http://www.cplusplus.com/doc/tutorial/typecasting/

以下引用自: https://stackoverflow.com/questions/573294/when-to-use-reinterpret-cast

Here is a variant of Avi Ginsburg’s program which clearly illustrates the property of reinterpret_cast mentioned by Chris Luengo, flodin, and cmdLP: that the compiler treats the pointed-to memory location as if it were an object of the new type:

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

class A
{
public:
    int i;
};

class B : public A
{
public:
    virtual void f() {}
};

int main()
{
    string s;
    B b;
    b.i = 0;
    A* as = static_cast<A*>(&b);
    A* ar = reinterpret_cast<A*>(&b);
    B* c = reinterpret_cast<B*>(ar);
    
    cout << "as->i = " << hex << setfill('0')  << as->i << "\n";
    cout << "ar->i = " << ar->i << "\n";
    cout << "b.i   = " << b.i << "\n";
    cout << "c->i  = " << c->i << "\n";
    cout << "\n";
    cout << "&(as->i) = " << &(as->i) << "\n";
    cout << "&(ar->i) = " << &(ar->i) << "\n";
    cout << "&(b.i) = " << &(b.i) << "\n";
    cout << "&(c->i) = " << &(c->i) << "\n";
    cout << "\n";
    cout << "&b = " << &b << "\n";
    cout << "as = " << as << "\n";
    cout << "ar = " << ar << "\n";
    cout << "c  = " << c  << "\n";
    
    cout << "Press ENTER to exit.\n";
    getline(cin,s);
}

Which results in output like this:

as->i = 0
ar->i = 50ee64
b.i   = 0
c->i  = 0

&(as->i) = 00EFF978
&(ar->i) = 00EFF974
&(b.i)   = 00EFF978
&(c->i)  = 00EFF978

&b = 00EFF974
as = 00EFF978
ar = 00EFF974
c  = 00EFF974
Press ENTER to exit.

It can be seen that the B object is built in memory as B-specific data first, followed by the embedded A object. The static_cast correctly returns the address of the embedded A object, and the pointer created by static_cast correctly gives the value of the data field. The pointer generated by reinterpret_cast treats b’s memory location as if it were a plain A object, and so when the pointer tries to get the data field it returns some B-specific data as if it were the contents of this field.

应用如下:
下面的应用根据输入的类型T判断后使用了reinterpret_cast去转换;

template <typename T>
void OptionManager::RegisterOption(const std::string& name, const T* option) {
  if (std::is_same<T, bool>::value) {
    options_bool_.emplace_back(name, reinterpret_cast<const bool*>(option));
  } else if (std::is_same<T, int>::value) {
    options_int_.emplace_back(name, reinterpret_cast<const int*>(option));
  } else if (std::is_same<T, double>::value) {
    options_double_.emplace_back(name, reinterpret_cast<const double*>(option));
  } else if (std::is_same<T, std::string>::value) {
    options_string_.emplace_back(name,
                                 reinterpret_cast<const std::string*>(option));
  } else {
    LOG(FATAL) << "Unsupported option type";
  }
}
void FloorDet::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { if (_c == QMetaObject::InvokeMetaMethod) { auto *_t = static_cast<FloorDet *>(_o); Q_UNUSED(_t) switch (_id) { case 0: _t->openCam(); break; case 1: _t->destroyCam(); break; case 2: _t->startCam(); break; case 3: _t->startcam(); break; case 4: _t->softCam(); break; case 5: _t->SendLog2((*reinterpret_cast< QString(*)>(_a[1]))); break; case 6: _t->sendtoolsA((*reinterpret_cast< cv::Mat(*)>(_a[1])),(*reinterpret_cast< cv::Mat(*)>(_a[2]))); break; case 7: _t->sendtoolsB((*reinterpret_cast< cv::Mat(*)>(_a[1])),(*reinterpret_cast< cv::Mat(*)>(_a[2]))); break; case 8: _t->chufa(); break; case 9: _t->cfclearD(); break; case 10: _t->pictureA11(); break; case 11: _t->pictureA12(); break; case 12: _t->pictureB1(); break; case 13: _t->pictureB2(); break; case 14: _t->pictureB3(); break; case 15: _t->XSzs_m((*reinterpret_cast< QString(*)>(_a[1]))); break; case 16: _t->XSng_m((*reinterpret_cast< QString(*)>(_a[1]))); break; case 17: _t->XSbb_m((*reinterpret_cast< QString(*)>(_a[1]))); break; case 18: _t->XSyw_m((*reinterpret_cast< QString(*)>(_a[1]))); break; case 19: _t->XShs_m((*reinterpret_cast< QString(*)>(_a[1]))); break; case 20: _t->XSll_m((*reinterpret_cast< QString(*)>(_a[1]))); break; case 21: _t->on_Start_clicked(); break; case 22: _t->on_Stop_clicked(); break; case 23: _t->on_pushButton_clicked(); break; case 24: _t->WriteLog((*reinterpret_cast< QString(*)>(_a[1]))); break; case 25: _t->clearD(); break; case 26: _t->showB1(); break; case 27: _t->showB2(); break; case 28: _t->showB3(); break; case 29: _t->showA11(); break; case 30: _t->showA12(); break; case 31: _t->showA21((*reinterpret_cast< QImage(*)>(_a[1]))); break; case 32: _t->showA22((*reinterpret_cast< QImage(*)>(_a[1]))); break; case 33: _t->showA31((*reinterpret_cast< QImage(*)>(_a[1]))); break; case 34: _t->showA32((*reinterpret_cast< QImage(*)>(_a[1]))); break; case 35: _t->YANSHI(); break; case 36: _t->writelogs((*reinterpret_cast< QString(*)>(_a[1])),(*reinterpret_cast< QString(*)>(_a[2]))); break; case 37: _t->LoadStationA21Img(); break; case 38: _t->LoadStationA22Img((*reinterpret_cast< std::string(*)>(_a[1]))); break; case 39: _t->LoadStationA31Img((*reinterpret_cast< std::string(*)>(_a[1]))); break; case 40: _t->LoadStationA32Img((*reinterpret_cast< std::string(*)>(_a[1]))); break; case 41: _t->resizeWindow(); break; default: ; } } else if (_c == QMetaObject::IndexOfMethod) { int *result = reinterpret_cast<int *>(_a[0]); { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::openCam)) { *result = 0; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::destroyCam)) { *result = 1; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::startCam)) { *result = 2; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::startcam)) { *result = 3; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::softCam)) { *result = 4; return; } } { using _t = void (FloorDet::*)(QString ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::SendLog2)) { *result = 5; return; } } { using _t = void (FloorDet::*)(cv::Mat , cv::Mat ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::sendtoolsA)) { *result = 6; return; } } { using _t = void (FloorDet::*)(cv::Mat , cv::Mat ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::sendtoolsB)) { *result = 7; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::chufa)) { *result = 8; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::cfclearD)) { *result = 9; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::pictureA11)) { *result = 10; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::pictureA12)) { *result = 11; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::pictureB1)) { *result = 12; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::pictureB2)) { *result = 13; return; } } { using _t = void (FloorDet::*)(); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::pictureB3)) { *result = 14; return; } } { using _t = void (FloorDet::*)(QString ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::XSzs_m)) { *result = 15; return; } } { using _t = void (FloorDet::*)(QString ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::XSng_m)) { *result = 16; return; } } { using _t = void (FloorDet::*)(QString ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::XSbb_m)) { *result = 17; return; } } { using _t = void (FloorDet::*)(QString ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::XSyw_m)) { *result = 18; return; } } { using _t = void (FloorDet::*)(QString ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::XShs_m)) { *result = 19; return; } } { using _t = void (FloorDet::*)(QString ); if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&FloorDet::XSll_m)) { *result = 20; return; } } } }解释一下这段代码
07-30
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值