为什么保护继承导致dynamic_cast失败? [英] Why does protected inheritance cause dynamic_cast to fail?

查看:883
本文介绍了为什么保护继承导致dynamic_cast失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我改变了我的C ++基类为 protected 继承和我的 dynamic_cast p>

为什么要将继承更改为 protected 更改 dynamic_cast

  struct Base {
static Base * lookupDerived //实际返回一个Derived *对象。
};

struct Derived:protected / *切换到public以使其工作* / Base {
static void test(){
Base * base = lookupDerived();

if(dynamic_cast< Derived *>(base)){
std :: cout< 它工作(我们必须使用公共继承)。 << std :: endl;
} else {
std :: cout<< 它失败了(我们必须使用受保护的继承)。 << std :: endl;
}
};


解决方案

您作为外部用户无法访问受保护或私人类的成员。这同样适用于受保护或私有继承。一个类的作者不希望外部用户访问受保护/私有父类超过他们希望外部用户访问受保护/私有成员。



一个原因:假设父类有一个非虚拟析构函数。从基类指针中删除实例派生类将导致未定义的行为。使父类受保护/私有意味着你不能这样做(见脚注)。



另一个原因:假设有问题的类的作者不想要外部用户有权访问父类的公共成员。可以使用公共继承( is-a )并将这些公共接口降级为受保护或私有,但这将违反Liskov替换原则。受保护或私有继承不是一种关系。这些公共方法变得受保护或私有,受保护或私有继承。 Liskov替换没有问题,因为protected / private继承不是



脚注:这里有一个丑陋的方法:Use C风格铸造。外部用户可以将
派生类指针转换为基类指针,即使基类不可访问。对我来说,这是使用 -Wold-style-cast -Werror 编译的另一个原因。


I changed my C++ base class to be protected inheritance and my dynamic_cast(s) stopped working.

Why should changing the inheritance to protected change the behavior of 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;
   }
};

解决方案

You as an outside user cannot access the protected or private members of a class. The same applies to protected or private inheritance. The authors of a class don't want outside users to access protected/private parent classes any more than they want outside users to access protected/private members.

One reason: Suppose the parent class has a non-virtual destructor. Deleting from an instance derived class from a base class pointer would result in undefined behavior. Making the parent class protected/private means you can't do this (see footnote).

Another reason: Suppose the authors of the class in question don't want outside users to have access to the public members of the parent class. One could use public inheritance (is-a) and demote those public interfaces to protected or private, but this would violate the Liskov substitution principle. Protected or private inheritance is not an is-a relationship. Those public methods become protected or private with protected or private inheritance. There's no problem with Liskov substitution because protected/private inheritance is not is-a.

Footnote: There is an ugly way around this: Use C-style casts. Outside users can cast a derived class pointer to a base class pointer, even if the base class is not accessible. To me, that's yet another reason to compile with -Wold-style-cast -Werror.

这篇关于为什么保护继承导致dynamic_cast失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆