代码之家  ›  专栏  ›  技术社区  ›  Alok Save

关于C++中运算符的几点疑惑

  •  6
  • Alok Save  · 技术社区  · 15 年前

    这个 reinterpret_cast 我们知道可以将任何指针类型转换为任何其他指针类型。关于这个演员,我想问的问题是:

    1. 重新解释演员 工作,什么魔法(内部实现)允许重新解释强制转换工作?
    2. 重新解释演员 ? 据我所知,它不能保证铸件的安全,所以在使用时要采取什么预防措施 reinterpret_cast?

    关于铸造操作员的另一个问题:
    static_cast , dynamic_cast , const_cast 重新解释演员 )都被称为 Operators i、 据我所知,这样说对吗 casting operators cannot be overloaded unlike most other operators

    9 回复  |  直到 15 年前
        1
  •  4
  •   Jerry Coffin    15 年前
    1. 没有魔法。 reinterpret_cast 能够
    2. 在一些情况下,你可以从歧视性的工会那里获得安全。例如,如果您正在读取网络数据包,并且读取的数据足以看到您接收到的是TCP数据包,那么您可以(相当)安全地 重新解释演员 从 IPHdr 到 TCPHdr (或者你碰巧用了什么名字)。编译器不会(通常也不会)做很多事情——任何安全性都取决于您的实现和实施。
    3. 我使用了我在2中描述的代码,处理不同类型的网络数据包。

    最后一个问题是:你可以为一个类重载casting:

    class XXX { 
    public:
        operator YYY() { return whatever; }
    };
    

    不过,这通常可以用于转换——无论是通过静态转换、C样式转换,还是隐式转换。C++ 0x允许你添加一个 explicit 限定符,所以它不会用于隐式转换,但是仍然无法区分静态的和C样式的转换。

        2
  •  2
  •   Cheers and hth. - Alf    15 年前

    首先,不清楚“非标准指针”是什么意思。我认为你的前提是有缺陷的。幸运的是,这似乎没有影响到问题。

    “它是怎么工作的?”好吧,正如你从名字中可以猜到的,其目的只是改变对位模式的解释,可能是适当的扩展或缩短。这是一种类型更改,其中位模式保持不变,但解释和概念值发生更改。它与保持概念值的类型变化(例如。 int 转换为 double )同时,根据需要更改位模式以保留概念值。但大多数情况下 reinterpret_cast

    “如何确保安全”,即了解编译器的工作,以及 重新解释演员 . :-)

    void* 指针用于模拟多态性。

    干杯。,

        3
  •  2
  •   Flexo - Save the data dump sunny moon    15 年前

    reinterpret_cast 完全没有理由认为这应该有效 . 就像说“相信我,我真的很想这么做”。从一个系统到下一个系统,这到底是什么是不可预测的。在您的系统上,它可能只是复制位模式,而在另一个系统上,它可以以某种(潜在有用的)方式转换它们。

    例如

    class Foo {
        int a;
    };
    
    class Bar {
        int a;
    };
    
    int main() {
    
      Foo a;
    
      // No inheritance relationship and not void* so must be reinterpret_cast 
      // if you really want to do it
      Bar *b = reinterpret_cast<Bar*>(&a);
    
      char buffer[sizeof(Bar)];
    
      Bar *c = reinterpret_cast<Bar*>(buffer); // alignment?
    
    }
    

    不管发生什么情况,我都很乐意让你这么做。有时候,如果你在做一些低级的操作,这可能就是你想要做的。(想象一下 char * 将缓冲区强制转换为用户定义的类型)

    潜在的陷阱是巨大的,即使是在最简单的情况下,如缓冲区,其中对齐可能是一个问题。

    与 dlsym (在Linux上,能够 void* 函数指针,它在C++中是其他未定义的行为。(某些系统可能使用单独的地址空间或不同大小的指针!)这只能用C++中的RealTytCube来完成。

        4
  •  1
  •   Edward Strange    15 年前
    1. 关于重新解释cast几乎没有什么保证,这就是为什么要避免这样做的原因。你只被允许从T1转换到T2,然后再回到T1,并且知道,如果有一些假设,最终的结果将与你开始时的结果相同。

    是的,他们是接线员。恐怕你不能凌驾于他们之上。

        5
  •  1
  •   Jimmy    15 年前

    一个“实际”的使用重新解释。

    class ClassWithHiddenVariables
    {
    private:
        int a;
        double m;
    public:
        void SetVariables(int s, int d)
        {
            a = s;
            m = d;
        }
    }; 
    

    这个类在应用程序中的一千个地方使用,没有问题。

    现在,因为某些原因,我想在一个特定的部分看到成员。但是,我不想触碰现有的类,所以打破规则如下。

    class ExposeAnotherClass
    {
    public:
        int a_exposed;
        double m_exposed;
    };
    

    当您想看到ClassWithHiddenVariables对象的成员时,请使用reinterpret_cast来强制转换以公开OtherClass。示例如下

    ClassWithHiddenVariables obj;
    obj.SetVariables(10, 20.02);    
    ExposeAnotherClass *ptrExposedClass;
    ptrExposedClass = reinterpret_cast<ExposeAnotherClass*>(&obj);  
    cout<<ptrExposedClass->a_exposed<<"\n"<<ptrExposedClass->m_exposed;
    

    我不认为这种情况发生在现实世界中。但这只是解释了将对象视为位模式的reinterpret_cast。

        6
  •  0
  •   sharptooth    15 年前

    reinterpret_cast 告诉编译器“闭嘴,这是T*类型的变量” 不安全 除非它真的是T*类型的变量。在大多数实现中,什么都不做-变量中的相同值被传递到目标。

    您的类可以有任何类型T*的转换运算符,并且这些转换将在某些条件下隐式调用,或者您可以使用 static_cast .

        7
  •  0
  •   DanDan    15 年前

        8
  •  -1
  •   Chris    15 年前

    reinterpret_cast相当于C风格的cast。它并不能保证什么;它是为了让你做你需要做的事,希望你知道你在做什么。

    如果你想确保安全,可以使用dynamic_cast,因为它就是这样做的。如果无法安全地完成强制转换,DyrimeCySCAST返回NULL或NulLPTR(C++0X)。

    使用“铸造操作器”铸造,如静态铸造、动态铸造等。。不能超载。直接转换可以,例如:

    class Degrees
    {
    public:
        operator double() { ... }
    };
    
        9
  •  -1
  •   Charles Salvia    15 年前

    我们所知道的重新诠释 将任何非标准指针强制转换为 另一个非标准指针。

    差不多,但不完全是。例如,不能使用reinterpret_cast来转换 const int* 给一个 int* const_cast .

    如何重新解释演员的工作,什么是魔术(内部 实现)允许

    根本没有魔法。最终,所有数据都只是字节。C++类型的系统仅仅是一个抽象层,它告诉编译器如何“解释”每个字节。一个 reinterpret_cast 类似于普通的C-cast,因为它只是简单地说“让类型系统见鬼去吧:将这些字节解释为X类型而不是Y类型!”

    不能保证铸造安全,所以 使用时应采取什么预防措施 重新解释演员?

    好, 本质上是危险的。你不应该用它除非你真的知道你在做什么。尝试使用 static_cast 相反。C++类型的系统将保护你不做任何危险的事情。 .

    这个运算符的实际用法是什么。我不是真的 在我的职业生涯中遇到过 不用这个就不能到处走动 从通常的int*到char*将是 非常乐于助人,非常感激。

    重新解释演员 距离 T* 给一个 T** 将块解释为指向下一个块的指针,而不是块本身。