我正在研究现有的大型项目,基本上是:
目前,使用智能指针存储子项,主要是为了避免在从文件读取和用户编辑图形期间构建图形时进行深层复制。
由于智能指针(std :: shared_ptr)不传播constness,我有以下选项:
我知道使用智能指针只是为了避免在树操作期间出现深拷贝,这不是在c ++ 11时代实现这一点并移动语义的好方法。用移动语义重写所有代码可能会在一天内完成,但这代表了相当大的工作。
在您看来,实现该模式的最好方法是什么,而不用移动语义重写所有?我想过包装std :: shared_ptr来传播constness,还有其他想法吗?
谢谢!
答案 0 :(得分:0)
我会使用选项3,但将子项存储在基类或组合对象中的私有成员变量中。
仅允许通过强制执行const正确性的getter访问子节点。
const getter返回一个原始指针到const。非const getter返回原始指针或共享指针。
类似的东西:
#include <iostream>
#include <memory>
#include <vector>
template<class Child>
class Parent {
private:
std::vector<std::unique_ptr<Child>> children_;
protected:
~Parent() = default;
public:
const Child* getChild(size_t child_number) const {
return children_.at(child_number).get();
}
Child* getChild(size_t child_number) {
return children_.at(child_number).get();
}
size_t getNumberOfChildren() const {
return children_.size();
}
void addChild(std::unique_ptr<Child> child) {
children_.emplace_back(std::move(child));
}
};
struct Node : Parent<Node> {
private:
std::string name_;
public:
Node(std::string name) : name_(std::move(name)) {}
void print() const { std::cout << "Node: " << name_ << "\n";}
void setName(const std::string& name) { name_ = name; }
void wrong() const {
//children_[0]->setName("Wrong"); // Not allowed
//getChild(0)->setName("Wrong"); // Not allowed
}
};
void printRecursive(const Node* node) {
if (node) {
node->print();
for (size_t i=0; i!=node->getNumberOfChildren(); ++i)
printRecursive(node->getChild(i));
}
}
int main() {
// Initialization
Node root("Root");
root.addChild(std::make_unique<Node>("Child 1"));
root.addChild(std::make_unique<Node>("Child 2"));
// "Computation" with pointer-to-const
const Node* root_ptr = &root;
printRecursive(root_ptr);
}
Live demo - using composition.
我在我的示例中使用了unique_ptr
而不是shared_ptr
,因为我可以,但您可能有充分的理由使用shared_ptr
。