gpt4 book ai didi

c++ - 派生自其实例以固定格式(数据库、MMF)驻留的基类……如何安全?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:24:03 30 4
gpt4 key购买 nike

(注意:我正在寻找关于正确搜索词的任何建议,以阅读此类问题。"Object-relational-mapping" 我想到了一个我可以找到一些好的现有技术……但我还没有看到任何适合这种情况的东西。)

我有一个非常通用的 class Node ,目前您可以将其视为有点像 DOM 树中的元素。这并不完全是正在发生的事情——它们是内存映射文件中的图形数据库对象。但对于所有实际用途而言,类比都相当接近,因此为简单起见,我将坚持使用 DOM 术语。

节点中嵌入的“标签”意味着您应该(理想情况下)能够使用它执行的一组特定操作。现在我正在使用派生类来执行此操作。因此,例如,如果您试图表示类似 HTML 列表的内容:

<ul>
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>

底层树将是七个节点:

+--UL                       // Node #1
+--LI // Node #2
+--String(Coffee) // Node #3 (literal text)
+--LI // Node #4
+--String(Tea) // Node #5 (literal text)
+--LI // Node #6
+--String(Milk) // Node #7 (literal text)

getString()已经是节点本身的原始方法,我可能只会制作 class UnorderedListNode : public Node , class ListItemNode : public Node .

继续这个假设,让我们想象一下,当程序员对他们手中的节点“类型”/标签了解更多时,我想帮助他们使用不太通用的功能。也许我想用树上的结构习语帮助他们,比如将字符串项添加到无序列表,或者将事物提取为字符串。 (这只是一个类比,所以不要太认真地对待例程。)

class UnorderedListNode : public Node {
private:
// Any data members someone put here would be a mistake!

public:
static boost::optional<UnorderedListNode&> maybeCastFromNode(Node& node) {
if (node.tagString() == "ul") {
return reinterpret_cast<UnorderedListNode&>(node);
}
return boost::none;
}

// a const helper method
vector<string> getListAsStrings() const {
vector<string> result;
for (Node const* childNode : children()) {
result.push_back(childNode->children()[0]->getText());
}
return result;
}

// helper method requiring mutable object
void addStringToList(std::string listItemString) {
unique_ptr<Node> liNode (new Node (Tag ("LI"));
unique_ptr<Node> textNode (new Node (listItemString));
liNode->addChild(std::move(textNode));
addChild(std::move(liNode));
}
};

向这些新的派生类添加数据成员不是一个好主意。 真正保留任何信息的唯一方法是使用 Node 的基础例程(例如,上面的 addChild 调用,或 getText )与树交互。因此,真正的继承模型——就存在的范围而言——在 C++ 类型系统之外。是什么造就了 <UL>节点“maybeCast”到 UnorderedListNode与 vtables/etc 无关。

C++ 继承有时看起来是对的,但通常感觉不对。我觉得我应该拥有独立于 Node 存在的类而不是继承,并且只是以某种方式作为“访问助手”与其协作......但我不太了解那会是什么样子。

最佳答案

我不确定我是否完全理解您打算做什么,但这里有一些您可能会觉得有用的建议。

绝对在继承的正确轨道上。所有的 UL 节点、LI 节点……等等都是 Node-s。完美的“is_a”关系,您应该从 Node 类派生这些类。

let's imagine I wanted to help the programmer use less general functions when they know more about the Node "type"/tag they have in their hands

...这就是虚函数的用途。

现在为 maybeCastFromNode方法。那是令人沮丧的。为什么要这么做?也许用于反序列化?如果是,那么我建议使用 dynamic_cast<UnorderedListNode *> .尽管如果继承树和虚拟方法设计良好,您很可能根本不需要 RTTI。

C++ inheritance looks right sometimes, but feels wrong usually.

这可能并不总是 C++ 的错 :-)

关于c++ - 派生自其实例以固定格式(数据库、MMF)驻留的基类……如何安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11167483/

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