c++ - 私有(private)范围内私有(private)继承的动态向下转换

标签 c++ casting private downcast

this question 的调整我遇到的。考虑:

class A {};

class B : private A {
   static void foo();
};

void B::foo(){
   B* bPtr1 = new B;
   A* aPtr1 = dynamic_cast<A*>(bPtr1); // gives pointer
   B* bPtr2 = dynamic_cast<B*>(aPtr1); // gives NULL
}

因为 aPtr1 实际上属于 B* 类型,并且我们可以完全访问 B 及其继承自A,我希望这两个 Actor 都能工作。但他们没有;为什么?还有其他方法可以实现这种 Actor 吗?

注意:

  • 如果 foo() 不是 B 的成员,则两个强制转换都会失败。
  • 如果 B 公开继承自 A,则两种转换都可以。

最佳答案

5.2.7(ISO/IEC 14882, 12/29/2003)在这一点上非常明确:

[about the expression dynamic_cast<T>(v)]

If T is “pointer to cv1 B” and v has type “pointer to cv2 D” such that B is a base class of D, the result is a pointer to the unique B sub-object of the D object pointed to by v. [... bla bla about cv1 and cv2 ...] and B shall be an accessible unambiguous base class of D (emphasis mine)

(记忆 11.2 “如果基类的一个发明的公共(public)成员是可访问的,则称该基类是可访问的。”)。

这解释了为什么第一个类型转换有效。现在,第二个:

[...]

Otherwise, a run-time check is applied to see if the object pointed or referred to by v can be converted to the type pointed or referred to by T.

The run-time check logically executes as follows:

  • If, in the most derived object pointed (referred) to by v, v points (refers) to a public base class subobject of a T object, and if only one object of type T is derived from the sub-object pointed (referred) to by v, the result is a pointer (an lvalue referring) to that T object.
  • Otherwise, if v points (refers) to a public base class sub-object of the most derived object, and the type of the most derived object has a base class, of type T, that is unambiguous and public, the result is a pointer (an lvalue referring) to the T sub-object of the most derived object.
  • Otherwise, the run-time check fails.

The value of a failed cast to pointer type is the null pointer value of the required result type. A failed cast to reference type throws bad_cast (18.5.2).

因此,您观察到的行为似乎是由于 private继承:即使基类可访问,也不是public,标准要求public,不可访问。

烦人,不是吗?我手头没有 C++0x 草稿,也许有人可以用它的引号来编辑我的答案,以防万一发生了变化。

Is there another way to achieve this cast?

这取决于你想做什么。基本上,私有(private)继承只是执行组合的另一种设备。如果你真的要返回一个指向私有(private)派生实例的指针,那么要么将继承公开,要么返回一个成员。

无论如何,你会很高兴知道 static_cast好像没有这个限制:

5.2.9. [about static_cast<T>(v)] [...]

An rvalue of type “pointer to cv1 B”, where B is a class type, can be converted to an rvalue of type “pointer to cv2 D”, where D is a class derived (clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is not a virtual base class of D. The null pointer value (4.10) is converted to the null pointer value of the destination type. If the rvalue of type “pointer to cv1 B” points to a B that is actually a sub-object of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the result of the cast is undefined.

所以如果你确定指针的实际动态类型是什么,你可以static_cast里面 foo .

我想了解有关为什么存在这种不一致的任何其他信息。

关于c++ - 私有(private)范围内私有(private)继承的动态向下转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6927895/

相关文章:

c++ - 使用类定义中的推断维度初始化静态常量多维数组

c++ - 为什么不邀请有序的 std::map 和有序的 std::set 使 transaction_safe?

ios - 如何访问返回类型为 UIViewController 的对象数组

java - 令人困惑 "override a private method"

c++ - OpenCV版本显示错误

c++ - 整数可以类型转换为指向整数的指针吗?

java - 为什么 Android 中的 Activity 对象被转换为接口(interface)?

swift - 遵守协议(protocol)并保持属性(property)私有(private)

python - python 私有(private)变量是否可以在不使用 object._className__attributeName 的情况下更改?

android - 内部错误 : Could not find . pro 文件