【发布时间】:2022-07-21 16:58:14
【问题描述】:
如果我有一个名为Node 的类,如果Node 类的对象知道它们的NodeType 并且NodeType 将用于强制转换为这样的特定接口,那会很糟糕:
// NodeType
enum class NodeType : uint8_t
{
None = 0,
Foo = 1 << 0,
Bar = 1 << 1,
FooBar = 1 << 2,
FooMask = Foo | FooBar,
BarMask = Bar | FooBar,
};
inline constexpr uint8_t operator&(const NodeType& t_lhs, const NodeType& t_rhs)
{
return static_cast<uint8_t>(t_lhs) & static_cast<uint8_t>(t_rhs);
}
// Base Node Class
class Node
{
public:
virtual NodeType GetNodeType() const = 0;
};
// Interfaces
class IFoo
{
public:
virtual ~IFoo() = default;
virtual void FooSpecificMethod() const = 0;
};
class IBar
{
public:
virtual ~IBar() = default;
virtual void BarSpecificMethod() const = 0;
};
// Derived Node Classes
class FooNode : public Node, public IFoo
{
public:
NodeType GetNodeType() const override { return NodeType::Foo; }
void FooSpecificMethod() const override { std::cout << "Foo.\n"; }
};
class BarNode : public Node, public IBar
{
public:
NodeType GetNodeType() const override { return NodeType::Bar; }
void BarSpecificMethod() const override { std::cout << "Bar.\n"; }
};
class FooBarNode : public Node, public IFoo, public IBar
{
public:
NodeType GetNodeType() const override { return NodeType::FooBar; }
void FooSpecificMethod() const override { std::cout << "Foo.\n"; }
void BarSpecificMethod() const override { std::cout << "Bar.\n"; }
};
// Use of NodeType and Interfaces
std::vector<std::unique_ptr<Node>> GetNodes()
{
std::vector<std::unique_ptr<Node>> nodes{};
nodes.push_back(std::make_unique<FooNode>());
nodes.push_back(std::make_unique<FooNode>());
nodes.push_back(std::make_unique<BarNode>());
nodes.push_back(std::make_unique<FooBarNode>());
nodes.push_back(std::make_unique<FooBarNode>());
nodes.push_back(std::make_unique<FooBarNode>());
return nodes;
}
int main()
{
std::vector<std::unique_ptr<Node>> nodes{ GetNodes() };
for (const auto& node : nodes)
{
if ((node->GetNodeType() & NodeType::FooMask) != 0)
dynamic_cast<const IFoo*>(node.get())->FooSpecificMethod();
}
for (const auto& node : nodes)
{
if ((node->GetNodeType() & NodeType::BarMask) != 0)
dynamic_cast<const IBar*>(node.get())->BarSpecificMethod();
}
}
我的目标是在多态集合中的对象上做类型特定的事情,就像在最后一个代码 sn-p 中一样。这是一个不好的方法吗?有没有更多的面向对象的方法?
【问题讨论】:
标签: c++