programming language
Revision | 02be6c45261925e49c25633b4e080a8acab761a9 (tree) |
---|---|
Time | 2020-11-23 19:38:14 |
Author | dhrname <dhrname@user...> |
Commiter | dhrname |
Add the appendChild method and new node class
@@ -52,6 +52,11 @@ public: | ||
52 | 52 | virtual Node* appendChild(Node* const) = 0; |
53 | 53 | |
54 | 54 | virtual bool isNode() = 0; |
55 | + | |
56 | + virtual bool isCaseOf(type_info&) = 0; | |
57 | + | |
58 | + /*getValueメンバ関数は、多重定義を想定しているので、必ずしもNode*となるとは限らない*/ | |
59 | + virtual Node* getValue() = 0; | |
55 | 60 | }; |
56 | 61 | |
57 | 62 | /*空のノードクラス*/ |
@@ -73,8 +78,14 @@ public: | ||
73 | 78 | Node* appendChild(Node*){return this;}; |
74 | 79 | bool isNode() |
75 | 80 | { |
76 | - return false; | |
77 | - } | |
81 | + return false; | |
82 | + }; | |
83 | + virtual bool isCaseOf(type_info& id) | |
84 | + { | |
85 | + return false; | |
86 | + }; | |
87 | + | |
88 | + virtual Node* getValue(){return this;}; | |
78 | 89 | }; |
79 | 90 | |
80 | 91 | EmptyNode* const emptynode = new EmptyNode(); |
@@ -83,7 +94,7 @@ EmptyNode* const emptynode = new EmptyNode(); | ||
83 | 94 | * Node抽象クラスに対する内部実装*/ |
84 | 95 | class BaseNode: public EmptyNode |
85 | 96 | { |
86 | -protected: | |
97 | +private: | |
87 | 98 | Node* parentNode; |
88 | 99 | Node* nextSibling; |
89 | 100 | Node* previousSibling; |
@@ -244,25 +255,38 @@ Node* BaseNode::removeChild(Node* const child) | ||
244 | 255 | |
245 | 256 | return child; |
246 | 257 | } |
258 | + | |
259 | +/*insertBefore メンバ関数 | |
260 | + * 子ノードのprevの前隣りに、nodeを挿入する | |
261 | + * 引数prevが空ノードであれば、親ノードに末子ノードとして登録される | |
262 | + *@param node | |
263 | + *@param prev | |
264 | + *@return 挿入されたnode | |
265 | + **/ | |
247 | 266 | Node* BaseNode::insertBefore(Node* const node, Node* const prev) |
248 | 267 | { |
249 | - this.throwArgumentError(node, "insertBefore"); | |
268 | + this->throwArgumentError(node, "insertBefore"); | |
250 | 269 | |
251 | - /*prevはemptynodeの可能性が含まれる*/ | |
252 | - this.throwNULLArgumentError(prev, "insertBefore"); | |
270 | + /*prevはemptynodeの可能性が含まれるので、throwArgumentErrorは使わない*/ | |
271 | + this->throwNULLArgumentError(prev, "insertBefore"); | |
272 | + | |
273 | + if (prev->getParent() != this) | |
274 | + { | |
275 | + throw std::invalid_argument("NotFoundError: prev is not child on the insertBefore"); | |
276 | + } | |
253 | 277 | |
254 | - /*祖先ノードの中に、今挿入しつつあるnodeと一致するものがあれば、参照エラー | |
278 | + /*祖先ノードの中に、今挿入しつつあるnodeと一致するものがあれば、階層の参照エラー | |
255 | 279 | * というのは、循環参照を引き起こすため*/ |
256 | 280 | Node* p = this; |
257 | 281 | |
258 | - while (p.isNode()) | |
282 | + while (p->isNode()) | |
259 | 283 | { |
260 | 284 | if (p == node) |
261 | 285 | { |
262 | - throw std::invalid_argument("Reference error on the insertBefore"); | |
286 | + throw std::invalid_argument("HierarchyRequestError on the insertBefore"); | |
263 | 287 | } |
264 | 288 | |
265 | - p = p->getParent(p); | |
289 | + p = p->getParent(); | |
266 | 290 | } |
267 | 291 | |
268 | 292 | Node* pnode = node->getParent(); |
@@ -312,9 +336,24 @@ Node* BaseNode::insertBefore(Node* const node, Node* const prev) | ||
312 | 336 | } |
313 | 337 | Node* BaseNode::appendChild(Node* const node) |
314 | 338 | { |
315 | - return this->parentNode; | |
339 | + return this->insertBefore(node, emptynode); | |
316 | 340 | } |
317 | 341 | |
342 | +template<typename T> | |
343 | +class node | |
344 | +{ | |
345 | +private: | |
346 | + T& nodeValue; | |
347 | + type_info valueType; | |
348 | + | |
349 | +public: | |
350 | + node(T& value) | |
351 | + : nodeValue(value), | |
352 | + valueType(typeid(T)) | |
353 | + {} | |
354 | + | |
355 | +}; | |
356 | + | |
318 | 357 | int main(int argc, char **argv) |
319 | 358 | { |
320 | 359 | std::string str1 = "ABC"; |