C++ C++;多重继承已知,如果它是“;是一个;直接层次路径外的类

C++ C++;多重继承已知,如果它是“;是一个;直接层次路径外的类,c++,polymorphism,multiple-inheritance,C++,Polymorphism,Multiple Inheritance,我有以下层次结构的类 A |-B I |-C-| A是系统的类;B和C是我自己的 在系统中还有一个函数,它返回指向实例的指针 我是一个最小类,如果可能的话,它甚至没有任何成员 当我这样做的时候 A* pA= A::GetInstance(); if(!pA) return; I* pI= dynamic_cast<I*>(pA); if(!pI) return; 首先将其投射到C,然后您知道它是I: A* pA= A::GetInstance(); if

我有以下层次结构的类

A
|-B   I
  |-C-|
A是系统的类;B和C是我自己的

在系统中还有一个函数,它返回指向实例的指针

我是一个最小类,如果可能的话,它甚至没有任何成员

当我这样做的时候

A* pA= A::GetInstance();
if(!pA)
    return;

I* pI= dynamic_cast<I*>(pA);
if(!pI)
    return;

首先将其投射到
C
,然后您知道它
I

A* pA= A::GetInstance();
if(!pA)
    return;

if( C* pC = dynamic_cast<C*>(pA) ) {
    I* pI= dynamic_cast<I*>(pC);
    if(!pI) return; // unnecessary, but you can keep it
    .
    .
    .
    /// do your thing with pI here
    .
    .
    .
}
A*pA=A::GetInstance();
如果(!pA)
回来
如果(C*pC=动态(pA)){
I*pI=动态投影(pC);
if(!pI)return;//不需要,但可以保留
.
.
.
///在这里用圆周率做你的事
.
.
.
}

首先将其投射到
C
,然后您知道它是一个
I

A* pA= A::GetInstance();
if(!pA)
    return;

if( C* pC = dynamic_cast<C*>(pA) ) {
    I* pI= dynamic_cast<I*>(pC);
    if(!pI) return; // unnecessary, but you can keep it
    .
    .
    .
    /// do your thing with pI here
    .
    .
    .
}
A*pA=A::GetInstance();
如果(!pA)
回来
如果(C*pC=动态(pA)){
I*pI=动态投影(pC);
if(!pI)return;//不需要,但可以保留
.
.
.
///在这里用圆周率做你的事
.
.
.
}
以下工作:

#include <cstdio>

class A { public: virtual ~A() { } };
class B : public A { };
class I { };
class C : public B, public I { };

int main()
{
    C c;
    A* a = &c;
    if (dynamic_cast<I*>(a))
        std::printf("it's a C\n");
    else
        std::printf("it's not a C\n");
    return 0;
}
#包括
类A{public:virtual~A(){};
B类:公共A{};
第一类{};
C类:公共B、公共I{};
int main()
{
C C;
A*A=&c;
if(动态_-cast(a))
std::printf(“它是一个C\n”);
其他的
std::printf(“它不是C\n”);
返回0;
}
注意
C
声明中的第二个
public

以下工作:

#include <cstdio>

class A { public: virtual ~A() { } };
class B : public A { };
class I { };
class C : public B, public I { };

int main()
{
    C c;
    A* a = &c;
    if (dynamic_cast<I*>(a))
        std::printf("it's a C\n");
    else
        std::printf("it's not a C\n");
    return 0;
}
class C: public B, I
{ //...
#包括
类A{public:virtual~A(){};
B类:公共A{};
第一类{};
C类:公共B、公共I{};
int main()
{
C C;
A*A=&c;
if(动态_-cast(a))
std::printf(“它是一个C\n”);
其他的
std::printf(“它不是C\n”);
返回0;
}
注意
C
声明中的第二个
public

class C: public B, I
{ //...
I
C
的私有基类,因为您没有指定
I
的访问权限。(您的
public
仅适用于
B
),因此
C
类型的对象实际上不是
I
<代码>动态\u cast只能遵循公共继承关系

如果将其更改为:

class C: public B, public I
{ //...
I
C
的私有基类,因为您没有指定
I
的访问权限。(您的
public
仅适用于
B
),因此
C
类型的对象实际上不是
I
<代码>动态\u cast只能遵循公共继承关系

如果将其更改为:

class C: public B, public I
{ //...


所以,
A
有虚拟函数,
I
没有?你能为类发布最小的代码吗?如果你考虑一下编译器在看什么,这实际上是有意义的:给定一个A*和
动态转换
,编译器应该做什么来决定如何到达那里?假设还有其他类型的对象也从这两者派生,比如
struct D:X,I{}@aschepler:析构函数是虚拟的。还有更多的虚拟方法@阿斯切普勒:手表窗口显示它是指向C的指针!如果我将其转换为C指针,转换不会失败!所以,
A
有虚拟函数,
I
没有?你能为类发布最小的代码吗?如果你考虑一下编译器在看什么,这实际上是有意义的:给定一个A*和
动态转换
,编译器应该做什么来决定如何到达那里?假设还有其他类型的对象也从这两者派生,比如
struct D:X,I{}@aschepler:析构函数是虚拟的。还有更多的虚拟方法@阿斯切普勒:手表窗口显示它是指向C的指针!如果我将其转换为C指针,转换不会失败!我觉得很奇怪。符合要求吗?没有必要。一个单独的
dynamic\u cast
就可以找到“堂兄”基类。@asch:提问者说它不起作用,即使在达到标准后,它也应该是无效的。我觉得很奇怪。符合要求吗?没有必要。单个
dynamic\u cast
可以找到“表亲”基类。@asch:提问者说它不起作用,即使在达到标准后,它也应该是私有的?我认为
的标准是
受保护的
?@Deduplicator 11.2p2:“在基类没有访问说明符的情况下,当使用类键
struct
定义派生类时,假定为
public
;当使用类键
class
定义类时,假定为
private
。“二等兵?我认为
的标准是
受保护的
?@Deduplicator 11.2p2:“在基类没有访问说明符的情况下,当使用类键
struct
定义派生类时,假定为
public
;当使用类键
class
定义类时,假定为
private
。“太多了!第二次传承中的公众话语是解决这一问题的关键!太多了!第二次传承中的公众话语是解决这一问题的关键!