c++ - Can you prevent inherited private members being called through the parent at compile time? -
if have feature rich class, possibly 1 not own/control, case want add functionality deriving makes sense.
occasionally want subtract well, disallow part of base interface. common idiom have seen derive , make member functions private , not implement them. follows:
class base { public: virtual void foo() {} void goo() { this->foo(); } }; class derived : public base { private: void foo(); };
someplace else:
base * b= new derived;
and yet place:
b->foo(); // way prevent @ compile time? b->goo(); // or this?
it seems if compilation doesn't know derived, best can not implement , have fail @ runtime.
the issue arises when have library, can't change, takes pointer base, , can implement of methods, not all. part of library useful, run risk of core dumping if don't know @ compile time functions call what.
to make more difficult, others may inherit class , want use library, , may add of functions didn't.
is there way? in c++11? in c++14?
let's analyze this, focused on 2 major points:
class base { public: virtual void foo() {} // 1) // ... class derived : public base // , 2)
in 1) tell world every object of base
offers method foo()
publicly. implies when have base*b
can call b->foo()
- , b->goo()
.
in 2) tell world class derived
publicly behaves base
. following possible:
void call(base *b) { b->foo(); } int main() { derived *b = new derived(); call(b); delete b; }
hopefully see there no way call(base*)
can know if b
derived , can't possibly decide @ compile-time if calling foo
wouldn't legal.
there 2 ways handle this:
- you change visibility of
foo()
. not want because other classes can derivebase
, wants callfoo
afterall. keep in mind virtual methods can private, should declarebase
as
class base { virtual void foo() {} public: void goo() { this->foo(); } };
- you can change
derived
inherits eitherprotected
orprivate
base
. implies nobody/only inheriting classes can "see"derived
base
, callfoo()
/goo()
not allowed:
class derived : private base { private: void foo() override; // friends of class can see base aspect // .... or // public: // way // void foo(); // allow access foo() }; // derived d; d.goo() // <-- illegal // d.foo() // <-- illegal because `private base` invisible
you should go latter because doesn't involve changing interface of base
class - "real" utility.
Comments
Post a Comment