【问题标题】:Why is this static_cast not allowed?为什么不允许这个 static_cast ?
【发布时间】:2014-01-15 05:37:53
【问题描述】:

我有一个 A 类对象,我想在自定义堆栈对象上分配它。为此,我只需将堆栈指针移动与对象大小一样多的字节并返回其先前的值:

class A : public B {}; //B is from a precompiled library

class stack {
public:
    stack(void): _top(&_storage[0]) {}

    template <typename T>
    inline T* push(void) {
        T* ptr = static_cast<T*>(_top);

        _top += sizeof(T);

        return ptr;
    }

    //...

private:
    char _storage[1024];
    char* _top;
};

stack _stack;

int main(int argc, char** argv) {
    A* a = _stack.push<A>(); //ignore the lack of a constructor call

    return 0;
}

Visual C++ 只是告诉我 static_cast 不能从 char* 转换为 A*。常规的 C 风格转换不会给我这个错误,但我宁愿更明确并避免动态转换(A 从另一个类继承,但对它没有的 vtable 没有贡献)。在这种情况下,两者有什么区别吗?

【问题讨论】:

    标签: c++ visual-c++ c++11 static-cast


    【解决方案1】:

    按设计。

    static_cast 转换并非旨在在不相关的指针类型之间进行转换,因为您需要使用reinterpret_cast。如果您想明确说明您正在做的演员表,请使用正确的演员表。在这种情况下,C 样式转换将执行 reinterpret_cast

    您确实需要研究不同的演员表运算符,因为dynamic_cast 上的评论也没有多大意义。

    【讨论】:

    • 我以为我理解 dynamic_cast 改变了对象的动态类型,这不正确吗?
    • @NmdMystery:没有什么能改变对象的动态类型。当一个对象被构造并且类型永远不会改变时,它就是一个类型(引用或指针可能具有不同的类型,如在基中,但对象始终是相同的类型)。同样,您能做的最好的事情就是找一本书或教程来消除您的疑虑。
    • 嗯,这是一个诚实的错误,我想我已经对每个演员的作用有了一个很好的了解。猜不到。
    • @NmdMystery:不用担心。如果它被认为不是一个诚实的错误,那么可能会有一些投票结束。
    【解决方案2】:

    正如其他人所说,解决方案是使用reinterpret_cast,这意味着在不相关的指针类型之间进行转换时使用:

    T* ptr = reinterpret_cast<T*>(_top);
    

    如果您改用placement new,您不仅可以避免转换问题,还可以解决不为具有构造函数的类型调用构造函数的问题:

    T* ptr = new(_top) T();
    

    【讨论】:

      【解决方案3】:

      没有从 char* 到 A* 的隐式或显式转换。您希望 reinterpret_cast 执行这种类型的转换。

      更多详情请见This SO answer

      【讨论】:

        猜你喜欢
        • 2017-01-11
        • 1970-01-01
        • 2020-06-24
        • 2013-09-07
        • 2021-10-13
        • 2013-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多