代码之家  ›  专栏  ›  技术社区  ›  Suma

安全转换为常量char*—临时生存期问题

  •  0
  • Suma  · 技术社区  · 14 年前

    我定义了以下模板,以便可以执行显式但安全的强制转换:

    /// cast using implicit conversions only
    template <class To,class From>
    inline To safe_cast( const From &from ) {return from;}
    

    通常(例如,当将参数传递到sprintf和类似函数时),我希望使用此模板执行从字符串类到C样式字符串的转换。但是,它表明,当临时文件通过时,这是不可能的,因为临时文件的寿命不够长。

    请考虑以下示例:

    class Object
    {
      public:
      MyStringClass GetDebugName() const;
    };
    
    Object obj;
    printf("%s",safe_cast<const char *>(obj.GetDebugName()));
    

    obj.getdebugname()中的临时变量仅在安全强制转换期间有效,并且指针在printf中无效(指向已被破坏的临时字符串的数据)。

    作为一个解决方法,我目前使用的是不带模板调用的直接强制转换: const char *c = (const char *)(obj.GetDebugName() 但这有一个缺点,即类型安全性降低,因为强制转换不必要地强(例如,即使obj.getDebugName()返回int而不是字符串值,强制转换也会自动成功)。 static_cast 可能会稍微好一点,但即使这太强了,我想得到一个错误的任何情况下,演员不一定是安全的。

    1)如果我没有弄错,标准规定临时寿命是一个声明(除非通过约束到常量引用来延长,在这种情况下,它是引用的寿命)。当查看上面的printf示例时,我不太确定“语句”是什么,以及我看到的行为是否一致。如果语句是整个printf,则const from&from的生存期较短-我应该从临时语句期望什么生存期?有人能解释清楚吗?

    2)是否有其他方法可以安全地进行转换,但转换结果的使用寿命是否足够长?

    编辑:

    请考虑一下这个更一般的问题,我正在寻找一种机制,对于临时的生命周期,如何进行这样的转换,我对任何特定的字符串类的特殊情况都不太感兴趣。

    为了澄清为什么我不想使用.c_str或类似的成员函数:我希望转换代码是类型不可知的,我不希望代码依赖于这样一个事实:我知道这个特定的字符串类型已经实现了c_str,我希望它能够工作,即使不同的字符串类将由ObjectDebugName返回,或者即使ObjectDebugName将返回已返回const char*(这排除了调用.operator const char*()的可能性。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Yakov Galka    14 年前

    我可以做一个明确但安全的演员表

    我将它称为显式执行的隐式强制转换,或者称为公正而显式的隐式强制转换。

    1)如果我没有弄错,标准规定临时寿命是一个声明(除非通过约束到常量引用来延长,在这种情况下,它是引用的寿命)。当查看上面的printf示例时,我不太确定“语句”是什么,以及我看到的行为是否一致。如果语句是整个printf,则const from&from的生存期较短-我应该从临时语句期望什么生存期?有人能解释清楚吗?

    你是对的,临时的被摧毁了 之后 printf已经返回。 您提供的代码应该有效。如果没有,就意味着你提供了一些重要的信息。

        2
  •  1
  •   CashCow    14 年前

    我不知道你为什么在这里使用自己的字符串类。这个类是否有一个成员函数来获取const char*呢?

    STD::字符串GEDUBGNAMEAD();

    printf(“%s”,getdebugname().c_str());

    例如,在该语句期间,临时语句将保持有效,这是安全的。

        3
  •  0
  •   MSalters    14 年前

    您可以直接调用转换函数:

    printf("%s", obj.GetDebugName().operator const char*());