换句话说,如果我有课
class A
{
public:
A() { .. }
virtual void somemethod() { .. }
};
可以写吗
class B : public A
{
public:
B() { .. }
protected:
virtual void somemethod() { .. }
};
还是这种方法有一些缺点?
换句话说,如果我有课
class A
{
public:
A() { .. }
virtual void somemethod() { .. }
};
可以写吗
class B : public A
{
public:
B() { .. }
protected:
virtual void somemethod() { .. }
};
还是这种方法有一些缺点?
这种方法的主要缺点是人们总是可以获取一个指针/引用A
并调用somemethod
where is public。你为什么想做这样的事情?如果B
是一个A
, 并且A
s 有一个public somemethod
那么s 也有B
。
我会说这违背了多态的目的,因为当您编写一个接受多态类型的函数时,派生类型应该同样适用于它:
void fun(A* a){
a->somemethod();
}
...
A* a = new B();
fun(a); // Shouldn't this work?!
// According to Liskov Principle, you are doing it wrong!
// but really who cares, it depends on your justification
// of a solution to the the problem at hand.
恕我直言,这取决于您要解决的具体问题,因为我不相信“总是”成功的“最佳实践”。
这种方法没有缺点。唯一的限制是B::somemethod()
不能用B
对象/指针/引用调用。现在只能使用A
' 的指针或引用来调用它。
事实上,我已经看到,有时这种限制是有意引入的。这样的场景是当开发人员class B
想要传达仅使用基类句柄以多态somemethod()
方式调用的消息时。
没有缺点。
但这样做并没有真正的优势。
您仍然可以somemethod()
通过指向案例类的指针进行访问。
所以在技术方面没有缺点也没有优势。
所以现在我们开始讨论使用你的对象是多么容易。这里有一个缺点,因为您混淆了对象的用户(为什么它在这个级别受到保护而不是较低级别)?因此,您正在为自己创造工作,记录您做出此决定的原因以及您试图通过使用此技术实现的目标。
你真正想要达到的目标是什么?