C++ 使用差异访问规范c+覆盖+;
我在参加iKM考试时遇到了一个问题。有一个基类,它有两个带有私有访问说明符的抽象方法。有一个派生类正在重写这些抽象方法,但具有受保护/公共访问说明符 我从未遇到过派生类中重写的方法具有不同访问规范的情况。允许这样做吗?如果是,它是否符合基础和派生(即安全可替代)之间的“是”关系 你能给我指一些参考资料吗?这些资料可以提供关于类的这种用法的更多细节C++ 使用差异访问规范c+覆盖+;,c++,C++,我在参加iKM考试时遇到了一个问题。有一个基类,它有两个带有私有访问说明符的抽象方法。有一个派生类正在重写这些抽象方法,但具有受保护/公共访问说明符 我从未遇到过派生类中重写的方法具有不同访问规范的情况。允许这样做吗?如果是,它是否符合基础和派生(即安全可替代)之间的“是”关系 你能给我指一些参考资料吗?这些资料可以提供关于类的这种用法的更多细节 谢谢。是的,只要签名相同,这是允许的。在我看来,是的,你是正确的,超越了能见度(例如,公共>私有)中断IS-A。我相信Scott Myers有效C++
谢谢。是的,只要签名相同,这是允许的。在我看来,是的,你是正确的,超越了能见度(例如,公共>私有)中断IS-A。我相信Scott Myers有效C++系列有一个关于这个问题的讨论。
允许,在两个方向(即从代码>私下<代码> >代码>公共< /代码>,从<代码>公共<代码> >代码>私下<代码> >
另一方面,我认为这不会破坏IS-A关系。我的论点基于两个事实:- 使用
(或Base&
)句柄,可以获得与以前完全相同的界面Base*
- 您完全可以(如果愿意的话)引入一个向前的方法,即
,并直接调用public
方法:与更多的输入相同private
是的,这是合法的,可访问性是静态检查的(不是动态检查的): 现在,你为什么要这么做?仅当您直接使用派生类
B
(f()的第二个参数)而不是通过基A
接口(f()的第一个参数)使用时,它才起作用。
如果你总是使用抽象的
A
接口(我通常会推荐),它仍然符合“IS-A”关系。正如许多人指出的那样,它是合法的
然而,“IS-A”部分并不是那么简单。当涉及到“动态多态性”时,“IS-A”关系成立,也就是说,你可以用Super做的所有事情,你也可以用派生实例做
<>但是,在C++中,我们也有一些经常被称为静态多态性的东西(模板,大多数时候)。考虑下面的例子:
class A {
public:
virtual int m() {
return 1;
}
};
class B : public A {
private:
virtual int m() {
return 2;
}
};
template<typename T>
int fun(T* obj) {
return obj->m();
}
A类{
公众:
虚拟整数m(){
返回1;
}
};
B类:公共A{
私人:
虚拟整数m(){
返回2;
}
};
模板
int fun(T*obj){
返回obj->m();
}
现在,当您尝试使用“动态多态性”时,一切似乎都正常:
A* a = new A();
B* b = new B();
// dynamic polymorphism
std::cout << a->m(); // ok
std::cout << dynamic_cast<A*>(b)->m(); // ok - B instance conforms A interface
// std::cout << b->m(); fails to compile due to overriden visibility - expected since technically does not violate IS-A relationship
A*A=newa();
B*B=新的B();
//动态多态性
std::cout m();//好啊
std::cout m();//ok-B实例符合一个接口
//std::cout m();由于覆盖的可见性而无法编译-由于技术上不违反IS-A关系,因此应为
。。。但当您使用“静态多态性”时,您可以说“IS-A”关系不再成立:
A* a = new A();
B* b = new B();
// static polymorphism
std::cout << fun(a); // ok
//std::cout << fun(b); // fails to compile - B instance does not conform A interface at compile time
A*A=newa();
B*B=新的B();
//静态多态性
std::难道我不认为它打破了is-a,但如果不买这本书,我就不知道了。斯科特·梅耶斯可能是,但他很少上网。
A* a = new A();
B* b = new B();
// static polymorphism
std::cout << fun(a); // ok
//std::cout << fun(b); // fails to compile - B instance does not conform A interface at compile time