我将我的 C++ 基类更改为 protected
继承并且我的 dynamic_cast
(s) 停止工作。
为什么将继承更改为 protected
会改变 dynamic_cast
的行为?
struct Base {
static Base *lookupDerived(); // Actually returns a Derived * object.
};
struct Derived : protected /* Switch this to public to get it working */ Base {
static void test() {
Base *base = lookupDerived();
if (dynamic_cast<Derived *>(base)) {
std::cout << "It worked (we must be using public inheritance)." << std::endl;
} else {
std::cout << "It failed (we must be using protected inheritance)." << std::endl;
}
};
最佳答案
作为外部用户,您无法访问类的 protected 或私有(private)成员。这同样适用于 protected 或私有(private)继承。类的作者不希望外部用户访问 protected /私有(private)父类,正如他们不希望外部用户访问 protected /私有(private)成员一样。
原因之一:假设父类有一个非虚析构函数。从基类指针的实例派生类中删除将导致未定义的行为。使父类 protected /私有(private)意味着您不能这样做(参见脚注)。
另一个原因:假设相关类的作者不希望外部用户访问父类的公共(public)成员。可以使用公共(public)继承 (is-a) 并将这些公共(public)接口(interface)降级为 protected 或私有(private)接口(interface),但这会违反 Liskov 替换原则。 protected 或私有(private)继承不是是一个 关系。这些公共(public)方法通过 protected 或私有(private)继承而变得 protected 或私有(private)。 Liskov 替换没有问题,因为 protected /私有(private)继承不是is-a。
脚注:有一个丑陋的解决方法:使用 C 风格的转换。外部用户可以投
派生类指针指向基类指针,即使基类不可访问。对我来说,这是使用 -Wold-style-cast -Werror
进行编译的另一个原因。
关于c++ - 为什么 protected 继承会导致 dynamic_cast 失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12765174/