gpt4 book ai didi

c++ - 多重继承和重复函数调用

转载 作者:行者123 更新时间:2023-11-30 04:35:50 26 4
gpt4 key购买 nike

我的情况类似于Multiple inheritance + virtual function mess .我在不太复杂的环境中复制了代码,以证明我感到困惑的地方。

我想知道 C 如何执行(但不访问)B1::method 和 B2::method,然后依次执行继承的方法。

我认为这是可行的(正确的)唯一方法是因为父类是将函数调用传播到子类的类,所以它直接访问 Bx 的虚表,而不是通过 C。

在任何一种情况下,它是安全的,还是未定义的行为,有什么陷阱等;什么是更好的方法。

#include <iostream>
#include <vector>

class A {
static std::vector<A*> listeners;
public:
static void propagate();
protected:
A() {
listeners.push_back(this);
}
~A() {
for (std::vector<A*>::iterator it = listeners.begin(); it != listeners.end(); ++it) {
if (*it == this) {
listeners.erase(it);
break;
}
}
}
virtual void method()=0;
};

std::vector<A*> A::listeners;

void A::propagate() {
for (unsigned int i=0; i < listeners.size(); ++i) {
listeners[i]->method();
}
}

class B1 : public A {
protected:
B1() {}
~B1() {}
void method() {
B1inhmethod();
}
virtual void B1inhmethod() {}
};
class B2 : public A {
protected:
B2() {}
~B2() {}
void method() {
B2inhmethod();
}
virtual void B2inhmethod() {}
};

class C : public B1, public B2 {
public:
C() {}
~C() {}
void B1inhmethod() {
std::cout << "\nB1method in C";
}
void B2inhmethod() {
std::cout << "\nB2method in C";
}
};

int main() {
C myclass;
A::propagate();
return 0;
}

输出:

B1inhmethod in C
B2inhmethod in C

最佳答案

我认为这是因为 C 继承了 A 的两份拷贝,一份来自 B1,一份来自 B2。继承图如下所示:

A       A
| |
B1 B2
\ /
\ /
C

当您创建 C 时,它会同时初始化 B1 和 B2 基类,这两个基类都会递归地初始化它们的 A 基类。这导致两个不同的指针被添加到 A 的主列表中——指向 C 的 B1 基对象的指针和指向 A 的 B2 基对象的指针。它们都是同一个对象的一部分——即 C 实例——但是因为有逻辑上是两个 A 基础对象,你会得到两个指针。然后,当您遍历 A 对象列表时,您会发现 C 的 B1 组件和 C 的 B2 组件,因此两条消息都会打印出来。

如果这不是您想要的,请考虑查看 virtual inheritance ,这将使 B1 和 B2 对象共享一个 A 基础对象。这样,只有该对象的一个​​拷贝会被添加到主列表中。当然,如果你这样做,你必须要小心,因为那样你就需要 C 有一个 method 的实现来避免歧义;如果您不定义它,则有两个 method 实现,但显然都不是正确的调用方法。

关于c++ - 多重继承和重复函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4953204/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com