I would like mark a class as deprecated using C++98 and the g++ compiler in order to receive a warning when this class is used directly, or when someone derives from this class.
Apparently, using __attribute__ ((__deprecated__))
works when the class is used, but not for inheritance.
For example:
#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();
}
I would expect to receive a warning from "class Bar : public Foo", but this is not the case (tested with g++ 5.2.1).
Is there a way to have a warning when deriving from a deprecated class?
The simplest way I can think to work around this is, instead of actually marking that class deprecated, make a private class of that class which is marked deprecated, and which it instantiates as a temporary variable in its constructor. So you will still get the deprecation warning if you instantiate a derived class.
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
}
};
This may be more complicated to implement if base
has many different constructors, but this at least gives the idea. In general whenever an instance of derived
is constructed, an instance of base
must be constructed -- one of the base ctors must run to completion before the lifetime of the derived
instance can begin.