gpt4 book ai didi

c++ - 决定将哪个派生类作为参数传递

转载 作者:搜寻专家 更新时间:2023-10-31 01:02:46 25 4
gpt4 key购买 nike

我正在为当前的设计而苦苦挣扎,想知道是否有可能在不使用转换方法的情况下决定调用哪个方法。假设我有一个基础 Fence 类。

目前,我的 worker 知道如何 build 木栅栏以及如何 build 倒钩铁丝网。他们可以将两个栅栏加在一起……但到目前为止,他们只学会了如何将木栅栏与木栅栏连接起来,以及如何将带倒钩的有线的与带倒钩的有线的连接起来。

但是他们可能会学到更多,Fence 类有一个虚拟的 addFence(const Fence& fence) 方法。

因为我想避免任何转换方法,所以我尝试在两个类中添加特殊的 addFence() 方法。这是一个例子:

class Fence {
public:
virtual void addFence(const Fence& fence) = 0;
...
};

class BarbWireFence : public Fence {
public:
...
void addFence(const Fence& fence) {
//only add such a fence, if it is a barb wired one
}
void addFence(const BarbWireFence& fence) {
//continue the fence with the given one
}
};

class WoodenFence : public Fence {
public:
...
void addFence(const Fence& fence) {
//only add the fence, if it is a wooden one
}
void addFence(const WoodenFence& fence) {
//continue the fence with the given one
}
};

现在我想做类似的事情

Fence *woodenFence1 = new WoodenFence();
Fence *woodenFence2 = new WoodenFence();
woodenFence1->addFence(*woodenFence2);

但由于运行时决定我有什么样的栅栏,我只有基本 Fence* 指针以及基本 class Fence 的定义用于最后一行。

那么有没有更好的实现来“自动”决定我有什么样的围栏?还是我应该使用完全不同的设计?

最佳答案

欢迎来到binary methods的精彩世界| .

这个问题没有令人满意的解决方案。您可能想了解 double dispatch和它更正式的兄弟the Visitor pattern .这两件事基本上是一样的,只是呈现方式略有不同。在最简单的情况下,您可以这样做:

class WoodenFence;
class BarbWireFence;

class Fence {
public:
virtual void addFence(const Fence& fence) = 0;
virtual void addMe(BarbWireFence& fence) const = 0;
virtual void addMe(WoodenFence& fence) const = 0;
...
};


class BarbWireFence : public Fence {
public:
...
void addFence(const Fence& fence) {
fence->addMe(*this);
}
void addMe(BarbWireFence& fence) const {
fence->addBarbWireFence(*this);
}
void addMe(WoodenFence& fence) const {
throw error("bad fence combo");
}

void addBarbWireFence(const BarbWireFence& fence) {
// actually add fence...
}
};

class WoodenFence : public Fence {
public:
...
void addFence(const Fence& fence) {
fence->addMe(*this);
}
void addMe(BarbWireFence& fence) const {
throw error("bad fence combo");
}
void addMe(WoodenFence& fence) const {
fence->addWoodenFenceFence(*this);
}

void addWoodenFence(const WoodenFence& fence) {
// actually add fence...
}

...
};

您可以想出当您添加 10 种其他栅栏类型时会发生什么。

人们可能会采取完全不同的方向,即模板化整个业务并摆脱 Fence 基类,因为它不提供类型安全的接口(interface)。

class BarbWireFence {
public:
...
void addSimilarFence(const BarbWireFence& fence) {
//continue the fence with the given one
}
};

class WoodenFence {
public:
...
void addSimilarFence(const WoodenFence& fence) {
//continue the fence with the given one
}
};

template <typename Fence>
void addFence (Fence& f1, const Fence& f2) {
f1->addSimilarFence(f2);
}

关于c++ - 决定将哪个派生类作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26590251/

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