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 callfooafterall. keep in mind virtual methods can private, should declarebaseas
class base { virtual void foo() {} public: void goo() { this->foo(); } }; - you can change
derivedinherits eitherprotectedorprivatebase. implies nobody/only inheriting classes can "see"derivedbase, 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