【问题标题】:Deprecate old name for class in C++弃用 C++ 中类的旧名称
【发布时间】:2013-07-15 19:05:15
【问题描述】:

我在一个已经大量重命名了它的所有类和函数的框架上工作,我创建了一个允许使用旧名称的转换头:

#define OldClassA NewClassA
#define OldClassB NewClassB
...

现在我希望编译器在使用旧名称时警告用户。我该怎么做?

int main(){
  NewClassA newA;
  OldClassA oldA; // <-- This one would emit a warning
}

【问题讨论】:

  • 临时修复:__attribute__((deprecated)) class OldClass: public NewClass {};
  • 不要使用#define 提供别名,这是不安全的。请改用typedef
  • @syam:纯粹是好奇,但你能举一个不安全的例子吗?
  • @KarolyHorvath 一旦你的用户发现他们一直在扯头发几个小时的原因是因为你的无范围 #define 搞砸了他们的代码的一部分与你的完全无关,他们会猎杀你,如果他们抓到你,会对你造成伤害。绝对不安全,对您用户的代码和您自己的健康都是如此……;)
  • @KarolyHorvath 这也是不安全的,因为任何老白痴都只能#undef OldClassA#define OldClassA MaliciousClassAtypedefusing 只能执行一次且无法撤消。

标签: c++ macros typedef c-preprocessor deprecated


【解决方案1】:

许多编译器支持#warning 指令。例如。 VS:http://msdn.microsoft.com/en-us/library/aa266053(v=vs.60).aspx 或 GCC: http://gcc.gnu.org/onlinedocs/cpp/Diagnostics.html

#warning "old class name is used"。或者在 C++11 中你可以使用static_assert

类似这样的:

#ifdef OldClassA
   #warning "old class name is used"

【讨论】:

  • 是的,但是你可以在 #define 中使用警告宏吗?例如:#define OldClassA #warning ("......") NewClassA
  • @azmeuk 你不能用#ifdef吗?
  • @azmeuk,技术上,你可以在 C++11 中使用 #define OldClassA _Pragma("message .....")。 AFAIK,#pragma message 在主要的三个编译器中。不过,这有点不合时宜,因为有static_assert
【解决方案2】:

这可能与编译器高度相关。

对于 GCC,http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Type-Attributes.html 的参考页面描述了 deprecated 属性,并提供了 typedefs 的示例,我认为它们应该适合您的需求:

typedef NewClassA OldClassA __attribute__ ((deprecated));

Clang 有类似的东西,见http://clang.llvm.org/docs/LanguageExtensions.html

对于 Visual C++,你可以试试它的 deprecated declaraton/pragma: http://msdn.microsoft.com/en-us/library/044swk7y(v=vs.80).aspx

【讨论】:

    【解决方案3】:

    正如其他人所说,这是非常特定于编译器的。假设您的类是用新名称定义的。以下是您可以使用 GCC 和 MSVC 执行的操作:

    class NewClassA {}; // Notice the use of the new name.
    
    // Instead of a #define, use a typedef with a deprecated atribute:
    
    // MSVC
    typedef NewClassA __declspec(deprecated) OldClassA;
    
    // GCC
    //typedef NewClassA __attribute__((deprecated)) OldClassA;
    
    int main(){
        NewClassA newA;
        OldClassA oldA;
    }
    

    MSVC 产量:

    警告 C4996:“OldClassA”:已宣布弃用

    GCC 产量:

    警告:不推荐使用“OldClassA”

    任一编译器都不会针对NewClassA newA; 发出警告。

    【讨论】:

      【解决方案4】:

      自 C++14 发布以来,您现在可以使用[[deprecated]] 属性,独立于编译器(只要编译器 当然,完全支持 C++14)。

      在你的情况下,你会使用:

      [[deprecated]]
      typedef NewClassA OldClassA;
      
      // You can also include a message that will show up in the compiler
      // warning if the old name is used:
      
      [[deprecated("OldClassA is deprecated; use NewClassA instead.")]]
      typedef NewClassA OldClassA;
      

      请注意,这仅在 gcc-4.9 中受支持(如果使用 gcc),您需要指定 -std=c++1y。我不了解 MSVC; clang 从 3.4 版开始支持此功能。

      请参阅http://josephmansfield.uk/articles/marking-deprecated-c++14.html 了解有关如何弃用除 typedef 之外的其他内容的更多详细信息。

      【讨论】:

        猜你喜欢
        • 2019-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-08
        • 2014-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多