正如Node
所公开的那样boost::shared_ptr
,实例的生命周期可能会受到 C++ 和 Python 的影响。Node
只要持有boost::shared_ptr
存在的 Python 对象的句柄, Python 就会使 C++对象保持活动状态。
Node
因此,在下面的代码中,让我们从一个名为spam
的前提条件开始graph
。代码使用 C++Node
实例以及 PythonNode
实例的引用计数进行注释。
# The node named 'spam' is held in
# graph's nodeMap.
# cpp count: 1; python count: 0
# Boost.Python creats a Python Node object
# that holds boost::shared_ptr<Node>.
node = graph.getNode('spam') # cpp count: 2; python count: 1
# Removes the boost::shared_ptr<Node> for
# 'spam' from graph.nodeMap.
graph.destroyNode('spam') # cpp count: 1; python count: 1
# The C++ Node is still alive because the
# Python Node holds a boost::shared_ptr<Node>
node.getName() # cpp count: 1; python count: 1
# When Python no longer has a handle to the
# Python Node object, it will be garbage
# collected, which in turn will destroy
# the held boost::shared_ptr<Node>
node = None # cpp count: 0; python count: 0
如果node.getName()
不应该在被破坏的情况下成功操作node
,则考虑显式管理状态。例如,node.destroy()
将在 中设置状态node
,并且成员函数将在执行操作之前检查状态。如果状态指示node
已被销毁,则引发异常或适当处理。
这是一个演示生命周期的基本示例:
#include <map>
#include <string>
#include <boost/make_shared.hpp>
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
class Node
{
public:
Node(std::string name)
: name_(name)
{
std::cout << "Node()" << std::endl;
}
~Node()
{
std::cout << "~Node()" << std::endl;
}
std::string name() { return name_; }
private:
std::string name_;
};
class Graph
{
public:
// @brief Add node by name.
void add_node(std::string name)
{
nodes_.insert(make_pair(name, boost::make_shared<Node>(name)));
}
/// @brief Destroy node by name.
void destroy_node(std::string name)
{
nodes_.erase(name);
}
// @brief Get node by name.
boost::shared_ptr<Node> get_node(std::string name)
{
nodes_type::iterator result = nodes_.find(name);
return (result != nodes_.end())
? result->second
: boost::shared_ptr<Node>();
}
private:
typedef std::map<std::string, boost::shared_ptr<Node> > nodes_type;
nodes_type nodes_;
};
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<Node, boost::shared_ptr<Node>,
boost::noncopyable>("Node", python::no_init)
.def("name", &Node::name)
;
python::class_<Graph, boost::noncopyable>("Graph")
.def("add_node", &Graph::add_node)
.def("get_node", &Graph::get_node)
.def("destroy_node", &Graph::destroy_node)
;
}
及其在 Python 中的用法:
>>> from example import Graph
>>> graph = Graph()
>>> graph.add_node('spam')
Node()
>>> node = graph.get_node('spam')
>>> print node.name()
spam
>>> graph.destroy_node('spam')
>>> print node.name()
spam
>>> graph = None
>>> node = None
~Node()
请注意Node
' 的析构函数仅在 Python 不再具有该对象的句柄时才被调用。