4

我想使用 C++98 和 g++ 编译器将一个类标记为已弃用,以便在直接使用此类或有人从此类派生时收到警告。

显然, using__attribute__ ((__deprecated__))在使用类时有效,但不适用于继承。

例如:

#if defined(__GNUC__)
# define DEPRECATED __attribute__ ((__deprecated__))
#else
# define DEPRECATED
#endif


class DEPRECATED Foo
{
public:
    explicit Foo(int foo) : m_foo(foo) {}
    virtual ~Foo() {}

    virtual int get() { return m_foo; }

private:
    int m_foo;
};


class Bar : public Foo // This declaration does not produce a compiler
                       // warning.
{
public:
    explicit Bar(int bar) : Foo(bar), m_bar(bar) {}
    virtual ~Bar() {}

    virtual int get() { return m_bar; }

private:
    int m_bar;
};

int main(int argc, char *argv[])
{
    Foo f(0); // This declaration produces a warning.
    Bar b(0); // This declaration does not produce a warning.
    return b.get();
}

我希望收到来自“class Bar:public Foo”的警告,但事实并非如此(使用 g++ 5.2.1 测试)。

从已弃用的类派生时,有没有办法发出警告?

4

1 回答 1

5

我能想到的解决这个问题的最简单方法是,而不是实际将该类标记为已弃用,而是为该类创建一个标记为已弃用的私有类,并将其实例化为其构造函数中的临时变量。因此,如果您实例化派生类,您仍然会收到弃用警告。

class base {
  class DEPRECATED deprecator {};
public:
  base() {
    deprecator issue_warning;
    (void) issue_warning; // this line is no-op to silence unused variable warning for local variable
  }
};

class derived : public base {
public:
  derived()
    : base()
  {
    // I am also deprecated, because I called the ctor for base
    // which instantiates a deprecated class
  }
};

如果有许多不同的构造函数,这可能实现起来更复杂base,但这至少给出了这个想法。通常,无论何时derived构造一个实例,都base必须构造一个实例——其中一个基本 ctor 必须在derived实例的生命周期开始之前运行完成。

于 2015-09-08T17:40:22.910 回答