在C++中弃用类的旧名称

21

我正在处理一个框架,框架大量修改了其类和函数名称,我创建了一个过渡头文件,使旧的名称仍然可用:

我在处理一个框架,该框架对其所有类和函数进行了大量重命名。我创建了一个过渡头文件,使得旧的名称仍然可用。

#define OldClassA NewClassA
#define OldClassB NewClassB
...

现在我希望编译器在使用旧名称时向用户发出警告。我该如何做?

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

3
临时解决方法:__attribute__((deprecated)) class OldClass: public NewClass {};(将旧类声明为已过时,在新类的基础上继承旧类) - user529758
12
不要使用 #define 来提供别名,这是不安全的。应该使用 typedef 代替。 - syam
@syam:纯粹出于好奇,你能给一个例子说明它不是“安全”的吗? - Karoly Horvath
2
@KarolyHorvath 一旦你的用户发现他们已经因为你没有作用域的 #define 而搞乱了与你无关的代码部分,他们会追杀你,并在抓到你时对你进行身体上的伤害。这绝对是不安全的,对你的用户代码和你自己的健康都有影响... ;) - syam
1
@KarolyHorvath 这也是不安全的,因为任何老百姓都可以随意使用 #undef OldClassA#define OldClassA MaliciousClassA。而 typedefusing 只能执行一次,无法撤销。 - Pharap
显示剩余2条评论
4个回答

25

就像其他人说的一样,这是非常与编译器有关的。假设你的类是用新名称定义的。以下是在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;,两个编译器均不发出警告。


8
这很可能高度依赖于编译器。
对于GCC,http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Type-Attributes.html的参考页面描述了deprecated属性,并且提供了typedef的示例,我认为这些示例可以满足您的需求。
typedef NewClassA OldClassA __attribute__ ((deprecated));

Clang有类似的功能,参见http://clang.llvm.org/docs/LanguageExtensions.html

对于Visual C++,您可以尝试使用它的deprecated声明/编译指示:http://msdn.microsoft.com/en-us/library/044swk7y(v=vs.80).aspx


7
自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的情况;从版本3.4开始,clang支持此功能。
有关如何标记除typedef之外的其他内容以使其过时的更多详细信息,请参见http://josephmansfield.uk/articles/marking-deprecated-c++14.html

1

2
是的,但你可以在 #define 中使用警告宏吗?例如:#define OldClassA #warning ("......") NewClassA - azmeuk
@azmeuk 你不能使用 #ifdef 吗? - user1744056
2
@azmeuk,从技术上讲,在C++11中可以使用#define OldClassA _Pragma("message .....")。据我所知,#pragma message在主要的三个编译器中都有。不过这有点失去了意义,因为有static_assert - chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接