class IFoo
{
public:
virtual ~IFoo() {}
virtualvoid ~Func() = 0;
};
class Foo : public IFoo
{
public:
Foo() {}
virtual ~Foo() {}
private:
void Func() {}
};
IFoo * p1 = new Foo();
Foo * p2 = new Foo();
p1->Func(); // fine, because public in IFoo
p2->Func(); // compiler error, because private in Foo
In fact I did a little more experimentation after discovering this and found out that you redefine the visibility of any virtual function in a subclass (private to public etc). The only time you will get a compiler error for calling a private function is when the instance you are calling from defines it as private.
My question is: Let's say that you want to enforce that you can't call Func() from anything but a pointer to the IFoo, is it a valid design strategy to hide it in the concrete class when it is public in the interface?
I know I'm probably violating some sacred c++ rule of good practice, but try as I might I couldn't find anything about it in books or online yet. Could someone point me to Meyer's or Sutter & Alexandrescu item that will set me straight and whack me over the head?
I know I'm probably violating some sacred c++ rule of good practice
You are. Inheritance forms an "is a" relationship. The Child "is a" Parent. If Poodle is derived from Dog, then a Poodle "is a" Dog.
Following that logic, anything you can do with a dog, you can also do with a poodle.
My question is: Let's say that you want to enforce that you can't call Func() from anything but a pointer to the IFoo,
You shouldn't need/want to do this. Since Foo "is an" IFoo, anything you can do with an IFoo you should also be able to do with a Foo -- otherwise you break the "is a" relationship.
Even if somehow what you wanted to do was possible, it would be easily side-stepped / abused.
Consider the following:
1 2 3 4 5 6 7 8 9 10
Foo f;
// what's the difference between this:
f.Func();
// and this?:
IFoo* p = &f;
p->Func();
// why allow one and not the other? It's nonsense.