Reputation: 2721
I have a base class which looks something like this:
class Base
{
public:
typedef std::shared_ptr<Base> ptr_t;
typedef std::weak_ptr<Base> wptr_t;
enum class Type { foo, bar, baz };
Type x;
// ...
};
I'd like those internal types to be public so that I can do stuff like Base::ptr_t my_ptr(new Base);
and so on. But if I make a new class like this...
class Derived : public Base
{
// ...
};
unfortunately, Derived::ptr_t
is still a Base pointer. I'd like Derived to publicly inherit x
from Base, but not inherit ptr_t
,wptr_t
, or Type
. For example
Derived a;
a.x = Base::Type::foo; // this should work
a.x = Derived::Type::foo; // but I want this to fail
Is this possible, perhaps though some magic use of friend
or virtual
or something like that?
Upvotes: 3
Views: 177
Reputation: 2721
Based on the answers of iammilind and Luc Danton, here's what I've come up with:
class Base
{
private:
// only 'BaseClass' is allowed to derive from Base
Base() { }
friend class BaseClass;
public:
typedef std::shared_ptr<Base> ptr_t;
typedef std::weak_ptr<Base> wptr_t;
enum class Type { foo, bar, baz };
Type x;
// ...
};
class BaseClass : public Base
{
private:
// make all the raw_Base types private
using Base::ptr_t;
using Base::wptr_t;
using Base::Type;
};
class Derived : public BaseClass
{
// define as usual, and now all is well in the world.
};
// now, to test it
class Derived2 : public Base { }; // fails
Derived d;
d.x = Derived::Type::foo; // fails
d.x = Base::Type::foo; // works
// Which is exactly what I wanted.
As far as I can tell, the only problem with this solution is that it adds a new and potentially confusing class. The class is defined in such a way that it can't really be misused – Base
itself cannot be derived from except by BaseClass
, but still, BaseClass
is an unattractive piece of namespace-clutter.
However, for the particular piece of code that I intend to use this in, I happen to be using the equivalent of BaseClass
already to solve an unrelated problem. So this BaseClass
technique suits my purposes just fine.
Upvotes: 0
Reputation: 70098
Simply override the type:
class Derived {
typedef int Type;
};
It will not allow the use of Derived::Type
(as it's private as well as typedef
ed)
Upvotes: 4
Reputation: 35469
class Derived : public Base
{
// This is now private
using Base::ptr_t;
using Base::wptr_t;
// ...
};
Upvotes: 3