C ++不安全的强制转换方法

塞布

在复杂的代码库中,我有一个非虚拟基类指针数组(该基类没有虚拟方法)

考虑以下代码:

#include <iostream>

using namespace std;

class TBase
{
    public:
        TBase(int i = 0) : m_iData(i) {}
        ~TBase(void) {}

        void Print(void) {std::cout << "Data = " << m_iData << std::endl;}

    protected:
        int     m_iData;
};

class TStaticDerived : public TBase
{
    public:
        TStaticDerived(void) : TBase(1) {}
        ~TStaticDerived(void)  {}
};

class TVirtualDerived : public TBase
{
    public:
        TVirtualDerived(void) : TBase(2) {}
        virtual ~TVirtualDerived(void) {} //will force the creation of a VTABLE
};

void PrintType(TBase *pBase)
{
    pBase->Print();
}

void PrintType(void** pArray, size_t iSize)
{
    for(size_t i = 0; i < iSize; i++)
    {
        TBase *pBase = (TBase*) pArray[i];
        pBase->Print();
    }
}


int main()
{
    TBase b(0);
    TStaticDerived sd;
    TVirtualDerived vd;

    PrintType(&b);
    PrintType(&sd);
    PrintType(&vd); //OK

    void* vArray[3];
    vArray[0] = &b;
    vArray[1] = &sd;
    vArray[2] = &vd; //VTABLE not taken into account -> pointer not OK
    PrintType(vArray, 3);

    return 0;
}

输出为(在Win64上与Mingw-w64 GCC 4.9.2编译):

Data = 0
Data = 1
Data = 2
Data = 0
Data = 1
Data = 4771632

失败的原因是,每个TVirtualDerived实例都有一个指向虚拟表的指针,而TBase没有。因此,没有先前的类型信息(从void *到TBase *)向上广播到TBase是不安全的。

问题是,我一开始就无法避免将其转换为void *。在基类上添加虚拟方法(例如析构函数)是可行的,但是会占用内存(我想避免)

语境:

我们正在非常受限的环境(内存受到严格限制)中实施信号/插槽系统。由于我们有数百万个可以发送或接收信号的对象,因此这种优化是有效的(当然,在可行时)

问题:

我怎么解决这个问题?到目前为止,我发现:

1-在TBase中添加虚拟方法。可行,但是并不能真正解决问题,可以避免。而且效率低下(内存过多)

2-强制转换为TBase *,而不是强制转换为数组中的void *,这是以失去通用性为代价的。(可能接下来我会尝试)

您看到其他解决方案了吗?

巴里

您必须考虑如何在内存中布置类。TBase很简单,一个成员只有四个字节:

 _ _ _ _
|_|_|_|_|
 ^
 m_iData

TStaticDerived是一样的 但是,TVirtualDerived完全不同。现在它的对齐方式为8,必须先从一个vtable开始,其中包含析构函数的条目:

 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
 ^               ^
 vtable          m_iData

所以,当你投vdvoid*,然后TBase*,您可以有效地重新诠释了前四个字节的虚函数表(偏移地址进入~TVirtualDerived())作为m_iData解决方案是先对static_castto执行操作TBase*,该操作将返回一个指针,以指向TBasein的正确起点vd然后返回void*

vArray[2] = static_cast<TBase*>(&vd); // now, pointer is OK

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Swift中强制转换为其他C结构不安全指针

来自分类Dev

不安全的C#-将不安全的指针传递给方法

来自分类Dev

numpy数组强制转换不安全

来自分类Dev

编译C#不安全代码

来自分类Dev

C#中的不安全结构

来自分类Dev

删除C#不安全指针

来自分类Dev

在C#中使不安全代码安全

来自分类Dev

在C#中使不安全代码安全

来自分类Dev

c ++加法标识不安全示例(a + 0.0!= a)

来自分类Dev

在C#中容纳嵌套的不安全结构

来自分类Dev

C ++-'localtime'此函数或变量可能不安全

来自分类Dev

C-为什么该程序不安全?

来自分类Dev

是否管理C#不安全代码?

来自分类Dev

在 Swift 中使用 C 库获取不安全的指针

来自分类Dev

在.C#和NET 5中,在struct和Span <byte>之间进行转换时没有不安全的情况,反之亦然

来自分类Dev

我可以将 IntPtr 的值转换为另一个 IntPtr 而不在 C# 中不安全吗?

来自分类Dev

使用AVAudioPCMBuffer将浮点值写入C#中的浮点指针数组(不安全或安全)

来自分类Dev

使用AVAudioPCMBuffer将浮点值写入C#中的浮点指针数组(不安全或安全)

来自分类Dev

C中的安全功能是否比不安全的功能更快?

来自分类Dev

这个不安全的 C++ 代码在 Python 中安全吗?

来自分类Dev

什么时候在 C# 中使用“不安全的字符串修改”是安全的?

来自分类Dev

从C#调用不安全的C ++时发生System.AccessViolationException

来自分类Dev

错误C4996:'scanf':该函数或变量在C编程中可能不安全

来自分类Dev

C ++的默认复制构造函数本质上是不安全的吗?迭代器从根本上来说也不安全吗?

来自分类Dev

TypeError:不安全的NumPy强制转换,必须显式强制转换与“”字符串混合的Python字符串

来自分类Dev

在C#中不安全代码的上下文中什么是不受信任的程序集

来自分类Dev

如何从字符串中删除不安全字符以登录C#

来自分类Dev

为什么C11标准不会丢弃不安全的strcat(),strcpy()函数?

来自分类Dev

错误C4996:'std :: _ Copy_impl':函数调用的参数可能不安全

Related 相关文章

  1. 1

    在Swift中强制转换为其他C结构不安全指针

  2. 2

    不安全的C#-将不安全的指针传递给方法

  3. 3

    numpy数组强制转换不安全

  4. 4

    编译C#不安全代码

  5. 5

    C#中的不安全结构

  6. 6

    删除C#不安全指针

  7. 7

    在C#中使不安全代码安全

  8. 8

    在C#中使不安全代码安全

  9. 9

    c ++加法标识不安全示例(a + 0.0!= a)

  10. 10

    在C#中容纳嵌套的不安全结构

  11. 11

    C ++-'localtime'此函数或变量可能不安全

  12. 12

    C-为什么该程序不安全?

  13. 13

    是否管理C#不安全代码?

  14. 14

    在 Swift 中使用 C 库获取不安全的指针

  15. 15

    在.C#和NET 5中,在struct和Span <byte>之间进行转换时没有不安全的情况,反之亦然

  16. 16

    我可以将 IntPtr 的值转换为另一个 IntPtr 而不在 C# 中不安全吗?

  17. 17

    使用AVAudioPCMBuffer将浮点值写入C#中的浮点指针数组(不安全或安全)

  18. 18

    使用AVAudioPCMBuffer将浮点值写入C#中的浮点指针数组(不安全或安全)

  19. 19

    C中的安全功能是否比不安全的功能更快?

  20. 20

    这个不安全的 C++ 代码在 Python 中安全吗?

  21. 21

    什么时候在 C# 中使用“不安全的字符串修改”是安全的?

  22. 22

    从C#调用不安全的C ++时发生System.AccessViolationException

  23. 23

    错误C4996:'scanf':该函数或变量在C编程中可能不安全

  24. 24

    C ++的默认复制构造函数本质上是不安全的吗?迭代器从根本上来说也不安全吗?

  25. 25

    TypeError:不安全的NumPy强制转换,必须显式强制转换与“”字符串混合的Python字符串

  26. 26

    在C#中不安全代码的上下文中什么是不受信任的程序集

  27. 27

    如何从字符串中删除不安全字符以登录C#

  28. 28

    为什么C11标准不会丢弃不安全的strcat(),strcpy()函数?

  29. 29

    错误C4996:'std :: _ Copy_impl':函数调用的参数可能不安全

热门标签

归档