c++ - 有哪些严酷的例子表明 C 风格的转换很糟糕?

标签 c++ casting

最近我找到了一个很好的例子来说明为什么 C 风格的转换很糟糕。我们从实现多个 COM 接口(interface)的以下类开始(为简洁起见,我有两个,但在现实生活中可能有十个):

class CMyClassInitial : public IInterface1, public IInterface2 {
    //declarations omitted
};

HRESULT CMyClassInitial::QueryInterface(REFIID iid, void** ppv)
{
    if( ppv == 0 ) {
       return E_POINTER;
    }
    *ppv = 0;
    if( iid == __uuidof(IUnknown) || iid == __uuidof(IInterface1) ) {
       *ppv = (IInterface1*)this;
    } else if( iid == __uuidof(IInterface2) ) {
       *ppv = (IInterface2*)this;
    } else {
       return E_NOINTERFACE;
    }
    AddRef();
    return S_OK;
}

上面的实现对 adjusting pointers to account for multiple inheritance 使用了 C-casts .它们甚至作为 static_cast 工作 - this 指针值将被适当调整。

现在我们将相同的 QueryInterface() 实现复制粘贴(或者我应该说重用代码?)到其他一些非常相似的类。

class CMyClassModified : public IInterface1 {
    //declarations omitted
};

并保持实现不变。新类不再继承自 IInterface2

} else if( iid == __uuidof(IInterface2) ) {
*ppv = (IInterface2*)this;
}

将编译得很好,C 风格的转换将充当 reinterpret_cast - this 指针值将被原封不动地复制。 调用者将获得一个指向实际未实现 IInterface2 的对象的指针 - 直接导致未定义行为。在一个巨大的数据库中,当有很多(不是我的例子中的两个)接口(interface)时,这样的问题很难被发现。

如果使用 static_cast 则不会发生 - 编译器会在尝试编译时发出错误

*ppv = static_cast<IInterface2*>(this);

在我看来,这是一个足够严酷的例子,说明使用 C 风格的转换会如何导致严重的问题。

还有哪些例子?

最佳答案

This FAQ item总结了为什么 C-cast 不好。

任何 C 风格的转换都可能是炸弹,因为它们通过使编译器静音来隐藏转换警告和错误。

既然你想要一个例子,这里是:

int main()
{
    float a = 0.123;
    double *b = ( double* ) &a;
    *b = 0.123;
}

关于c++ - 有哪些严酷的例子表明 C 风格的转换很糟糕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4884847/

相关文章:

Swift 无法在循环中推断条件类型

c++ - C++ 中的容器失效是什么意思?

c++ - CUDA:请帮我找出代码中的错误

在 C 中使用指针进行转换

c - C 中的运算符优先级和结构定义

java - 线程 "main"java.lang.ClassCastException : [Ljava. lang.Object 中的异常;不能转换为 model.AdminPopulate

c# - 在 ulong 和 long 变量之间强制添加

c++ - 数值转换

c++ - SSE 内在函数导致正常的浮点运算返回 -1.#INV

c++ - 如何从 C/C++ 中终止 MATLAB m 文件函数?