patterncppMinor
C++ Tree Class implementation
Viewed 0 times
implementationclasstree
Problem
I am trying to implement a class for the Node of a Tree in C++ in order to represent an HTML structure.
It is not complete by a shot, but i'd still like an opinion.
TreeNode.h :
TreeNode.cpp :
```
#include "TreeNode.h"
#include
#include
#include
TreeNode::TreeNode() {};
TreeNode::TreeNode(std::string iTextContent, std::string iTagName) :
textContent(iTextContent),
tagName(iTagName),
parent(NULL)
{}
int TreeNode::countNodesRec(TreeNode *root, int& count)
{
TreeNode *parent = root;
TreeNode *child = NULL;
for(int it = 0; it childrenNumber(); it++)
{
child = parent->getChild(it);
count++;
//std::coutgetTextContent()childrenNumber() > 0)
{
countNodesRec(child, count);
}
}
return count;
}
void TreeNode::appendChild(TreeNode *child)
{
child->setParent(this);
children.push_back(child);
}
void TreeNode::setParent(TreeNode *theParent)
{
parent = theParent;
}
void TreeNode::popBackChild()
{
children.pop_back();
}
void TreeNode::removeChild(int pos)
{
if(children.size() > 0) {
children.erase(children.begin()+ pos);
}
else {
children
It is not complete by a shot, but i'd still like an opinion.
TreeNode.h :
#ifndef TreeNode_H
#define TreeNode_H
#include
#include
class TreeNode
{
private:
std::string textContent;
std::string tagName;
TreeNode *parent;
std::vector children;
int countNodesRec(TreeNode *root, int& count);
public:
TreeNode();
TreeNode(std::string iTextContent, std::string iTagName);
void appendChild(TreeNode *child);
void setParent(TreeNode *parent);
void popBackChild();
void removeChild(int pos);
bool hasChildren();
bool hasParent();
TreeNode* getParent();
TreeNode* getChild(int pos);
int childrenNumber();
int grandChildrenNum();
std::string getTextContent();
std::string getTagName();
};
#endifTreeNode.cpp :
```
#include "TreeNode.h"
#include
#include
#include
TreeNode::TreeNode() {};
TreeNode::TreeNode(std::string iTextContent, std::string iTagName) :
textContent(iTextContent),
tagName(iTagName),
parent(NULL)
{}
int TreeNode::countNodesRec(TreeNode *root, int& count)
{
TreeNode *parent = root;
TreeNode *child = NULL;
for(int it = 0; it childrenNumber(); it++)
{
child = parent->getChild(it);
count++;
//std::coutgetTextContent()childrenNumber() > 0)
{
countNodesRec(child, count);
}
}
return count;
}
void TreeNode::appendChild(TreeNode *child)
{
child->setParent(this);
children.push_back(child);
}
void TreeNode::setParent(TreeNode *theParent)
{
parent = theParent;
}
void TreeNode::popBackChild()
{
children.pop_back();
}
void TreeNode::removeChild(int pos)
{
if(children.size() > 0) {
children.erase(children.begin()+ pos);
}
else {
children
Solution
Some quick comments:
Const correctness
You really should make your code const correct.
For example at least these functions could be const declared:
Use references to avoid copies
This:
should be:
otherwise you are creating temporary copies of the strings when you pass them in.
These functions should return by const reference:
Like so:
Otherwise you will be creating unnecessary memory copies each time the function is called even if you just want to look at the value.
Memory leak galore?
Your API requires that you pass in raw pointers and store them in the node. There is no documentation of the ownership of the pointers. Who is responsible for freeing them? Right now all I see is a memory leak waiting to happen.
In your main code you allocate the nodes with
Now, this keeping track of new/delete gets error prone very quickly so since C++11 you are recommended to use smart pointers. A.k.a.
Also you might be interested in reading up on Resource Acquisition Is Initialisation (RAII). We ❤❤❤ RAII in C++.
Const correctness
You really should make your code const correct.
For example at least these functions could be const declared:
bool hasChildren();
bool hasParent();
TreeNode* getParent();
TreeNode* getChild(int pos);
int childrenNumber();
int grandChildrenNum();
std::string getTextContent();
std::string getTagName();Use references to avoid copies
This:
TreeNode(std::string iTextContent, std::string iTagName);should be:
TreeNode(const std::string& iTextContent, const std::string& iTagName);otherwise you are creating temporary copies of the strings when you pass them in.
These functions should return by const reference:
std::string getTextContent();
std::string getTagName();Like so:
const std::string& getTextContent() const;
const std::string& getTagName() const;Otherwise you will be creating unnecessary memory copies each time the function is called even if you just want to look at the value.
Memory leak galore?
Your API requires that you pass in raw pointers and store them in the node. There is no documentation of the ownership of the pointers. Who is responsible for freeing them? Right now all I see is a memory leak waiting to happen.
In your main code you allocate the nodes with
new but C++ is NOT a garbage collected language. You will need to pair each new with a delete to free the memory otherwise you will run out of memory faster than you can say "Holy memory management batman!".Now, this keeping track of new/delete gets error prone very quickly so since C++11 you are recommended to use smart pointers. A.k.a.
std::unique_ptr and std::shared_ptr for just about everything. See also std::make_unique and std::make_shared. There are places where you could/should use pointers, but as I gather that you are new to C++ I will not go into those detail because you can get away with just using smart pointers everywhere for now.Also you might be interested in reading up on Resource Acquisition Is Initialisation (RAII). We ❤❤❤ RAII in C++.
Code Snippets
bool hasChildren();
bool hasParent();
TreeNode* getParent();
TreeNode* getChild(int pos);
int childrenNumber();
int grandChildrenNum();
std::string getTextContent();
std::string getTagName();TreeNode(std::string iTextContent, std::string iTagName);TreeNode(const std::string& iTextContent, const std::string& iTagName);std::string getTextContent();
std::string getTagName();const std::string& getTextContent() const;
const std::string& getTagName() const;Context
StackExchange Code Review Q#135432, answer score: 8
Revisions (0)
No revisions yet.