gpt4 book ai didi

c++ - 定义一个被多次继承的虚方法

转载 作者:太空狗 更新时间:2023-10-29 21:33:45 24 4
gpt4 key购买 nike

我一直在努力寻找这个问题的答案,但我找不到(我什至不知道如何正确表述)所以我决定在 StackOverflow 上写我的第一篇文章 =)。

上下文如下:

我有这个父类:

class Parent
{
public:
Parent(){};
void foo(void)
{
//Do some common things
bar();
//Do some more common things
};
protected:
virtual void bar(void) = 0;
};

我想创建无限数量的派生 Childs:

class Child1 : public Parent
{
public:
Child1() : Parent(), child1Variable(0) {};
protected:
virtual void bar(void) = 0;
private:
uint32_t child1Variable;
};

class Child2 : public Parent
{
public:
Child2() : Parent(), child2Variable(0) {};
protected:
virtual void bar(void) = 0;
private:
uint32_t child2Variable;
};

.
.
.

class ChildN : public Parent
{
public:
ChildN() : Parent(), childNVariable(0) {};
protected:
virtual void bar(void) = 0;
private:
uint32_t childNVariable;
};

主要是没有重复Parent的foo()中的代码

然后我想创建我的最终可实例化类,例如:

class ExampleFinal : public Child1, public Child3, public Child27
{
//How to define Child1::bar(), Child3::bar() and Child27::bar() ??
private:
void bar(void); //????
};

所以问题是:

  1. 我如何定义方法(滥用符号)ExampleFinal::Child1::bar, ExampleFinal::Child3::bar, ...
  2. 我是不是太拘泥于此而忽略了一个更简单的解决方案?

最终目标是能够做如下事情:

ExampleFinal test;
test.Child1::foo(); //should end up on "ExampleFinal::Child1::bar"
test.Child3::foo(); //should end up on "ExampleFinal::Child3::bar"

谢谢!

最佳答案

实现 ExampleFinal::bar() (旁注:bar(void) 是 C-ism,在 C++ 中没有用)将覆盖所有 bar你已经立即声明了。如果你想有不同的版本,你需要插入另一层类:

struct GrandChild1 : Child1 {
void bar() override { /*...*/ }
};

// And so on...

struct ExampleFinal : GrandChild1, GrandChild3, GrandChild27 {
// Nothing needed here.
};

然后您描述的行为将起作用。但是请注意,您的继承图意味着 ExampleFinal有一个Parent子对象 per Child 。这本身不是问题,但可能无法为您想要的模型建模——也许您需要此处的虚拟继承,但要当心兔子洞。


如果您想保留所有 ChildN::bar 的覆盖里面的ExampleFinal ,您可以添加标签分派(dispatch)来辨别它们,但代价是多一次虚拟调用:

struct Parent {
void foo() {
bar();
};

protected:
template <class Child>
struct tag { };
virtual void bar() = 0;
};

struct Child1 : Parent {
protected:
virtual void bar(tag<Child1>) = 0;

void bar() final override {
return bar(tag<Child1>{});
}

int child1Var;
};

struct Child2 : Parent {
protected:
virtual void bar(tag<Child2>) = 0;

void bar() final override {
return bar(tag<Child2>{});
}

int child2Var;
};

struct ExampleFinal : Child1, Child2 {
protected:
using Parent::tag;

void bar(tag<Child1>) final override {
std::cout << "Child1::bar\n";
}

void bar(tag<Child2>) final override {
std::cout << "Child2::bar\n";
}
};

请注意 bar()bar(tag<ChildN>)桥可以很容易地隐藏在宏后面。如果想避免第二次虚拟通话的成本,这里也可以应用CRTP。

关于c++ - 定义一个被多次继承的虚方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50097546/

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