为什么使用Boost.Intrusive容器来存储多态对象呢?

时间:2018-03-12 09:16:45

标签: c++ boost polymorphism

这是一个经常重复的建议,不应该从具有非虚析构函数的类继承(如果打算使用动态多态)。这就是继承标准容器类被认为是个坏主意的原因。

另一方面,Boost.Intrusive显式states其容器适合存储多态对象。在链接的示例中,这是通过派生自Traceback (most recent call last): File "C:/Users/xxx/PycharmProjects/Trading-Brain-master/examples/tf_example.py", line 203, in <module> main(args) File "C:/Users/xxx/PycharmProjects/Trading-Brain-master/examples/tf_example.py", line 183, in main runner = Runner(w, config, saveloc, args.load, sess) File "C:/Users/xxx/PycharmProjects/Trading-Brain-master/examples/tf_example.py", line 109, in __init__ self.agent = Agent(config, sess, load, self.step_op) File "C:\Users\xxx\PycharmProjects\Trading-Brain-master\tbrn\agents\tf\tf_agent.py", line 13, in __init__ self.brain = TFBrain(config, sess, load, step_op) File "C:\Users\xxx\PycharmProjects\Trading-Brain-master\tbrn\brains\tf\tf_brain.py", line 92, in __init__ self.writer = tf.summary.FileWriter('.\logs/%s' % self.model_dir, self.sess.graph) File "C:\Users\xxx\venv\lib\site-packages\tensorflow\python\summary\writer\writer.py", line 350, in __init__ filename_suffix) File "C:\Users\xxx\venv\lib\site-packages\tensorflow\python\summary\writer\event_file_writer.py", line 67, in __init__ gfile.MakeDirs(self._logdir) File "C:\Users\xxx\venv\lib\site-packages\tensorflow\python\lib\io\file_io.py", line 368, in recursive_create_dir pywrap_tensorflow.RecursivelyCreateDir(compat.as_bytes(dirname), status) File "C:\Users\xxx\venv\lib\site-packages\tensorflow\python\framework\errors_impl.py", line 473, in __exit__ c_api.TF_GetCode(self.status.status)) tensorflow.python.framework.errors_impl.NotFoundError: Failed to create a directory: .\logs/TradingGame/action_size-3/amp_scale-2/batch_size-64/discount-0.99/double_q-True/dueling-True/env_name-TradingGame/ep_end-0.0/ep_end_t-14400/ep_start-1.0/history_length-1/input_size-2; No such file or directory Process finished with exit code 1 来实现的,该boost::intrusive::list_base_hook<>没有虚拟析构函数,只在派生类中引入了一个。

  1. 这是一个有效的设计吗?
  2. 如果是这样,为什么以及如何符合我上面提到的一般建议?特别是,为什么同样的逻辑不能证明从标准容器继承?
  3. (请注意,我的问题不是关于标准容器和Boost.Intrusive容器之间的区别。我对正确使用Boost.Intrusive感兴趣,但我只提到标准容器作为一个例子,因为它们经常出现在类似主题的时候讨论)。

1 个答案:

答案 0 :(得分:2)

只有当派生类的使用涉及通过指向基类的指针对象的所有权时,才应该从具有非虚拟析构函数的类继承。标准容器类没有什么特别之处。继承它们并不是一个坏主意,但问题是其他扩展功能的方法应该是首选:添加独立的功能或聚合。

boost::intrusive::list_base_hook<>派生是一个完全有效的设计,因为派生对象的所有权永远不会通过指向list_base_hook的指针来保存。请注意,库提供了通过聚合挂钩(使用list_member_hook),这应该优先于继承。