C++ 面向对象设计问题(MFC&x2B;&x2B;实现)

C++ 面向对象设计问题(MFC&x2B;&x2B;实现),c++,oop,mfc,C++,Oop,Mfc,我有一个GUI与用户交互,但我有一个OOP设计问题 用户通过对话框指定CDiscreteDistributions,并将其存储在MyAppDoc类中的std::vector中进行序列化。通过另一个对话框,用户为特定的CParameter选择一种类型的CDistributionCDDiscretedDistribution、CConstantDistribution和CContinuousDistribution继承CDDistribution,并且CParameter具有指向CDDistribu

我有一个GUI与用户交互,但我有一个OOP设计问题

用户通过对话框指定
CDiscreteDistribution
s,并将其存储在
MyAppDoc
类中的
std::vector
中进行序列化。通过另一个对话框,用户为特定的
CParameter
选择一种类型的
CDistribution
CDDiscretedDistribution
CConstantDistribution
CContinuousDistribution
继承
CDDistribution
,并且
CParameter
具有指向
CDDistribution
成员变量的多态指针
MyAppDoc
的容器类为
CParameter
。因此,
CDiscreteDistribution
s被指向两次,但只存在一次

总之,
MyAppDoc
具有

  • std::vector
  • CContainer
    其中有许多
    CParameter
    具有
    • cddistribution*
      可以指向以下内容之一:
      • CDiscreteDistribution
        这是上面存储的
        CDiscreteDistribution*
        s之一
      • CConstantDistribution
        CParameter创建/销毁
      • CContinuousDistribution
        CParameter创建/销毁
  • 由于双重删除和序列化(boost),这种设计模式让我在移植应用程序时做了各种噩梦,使用
    shared_ptr
    。指向
    CDiscreteDistribution
    的指针之一是否应该是
    弱\u ptr
    ?如果是,指针应该在哪里

    谢谢你的帮助


    编辑: 我重新思考了使用
    std::vector
    的原因,只是为了避免将该向量复制到GUI中或从GUI中复制出来。但是对象非常小,因此我打破了它们之间的链接,并受到了性能方面的影响。现在
    MyAppDoc
    有:

  • std::vector
  • CContainer
    其中有许多
    CParameter
    具有
    • cddistribution*
      可以指向以下内容之一:
      • CDiscreteDistribution
        CParameter
        创建/销毁,从上面存储的
        CDiscreteDistribution
        之一复制而来
      • CConstantDistribution
        CParameter创建/销毁
      • CContinuousDistribution
        CParameter创建/销毁
  • 我认为问题的一部分是
    boost::serialization
    为每个
    CDiscreteDistribution
    创建了两个
    共享的\u ptr
    。现在唯一的问题是与以前版本创建的文件的向后兼容性


    我认为这个“解决方案”实际上只是在避免一个合适的设计

    对该问题的描述不足以理解全部情况、复杂情况和确切问题,而是一般情况-

    • 我假设您希望使用shared_ptr,而不必手动删除()对象

    • 如果是这样的话,看看是否可以通过不使用shared_ptr,而是使用boost::ptr_vector而不是原始指针向量来解决这个问题;然后,ptr_向量将为您处理内存管理


    我甚至不确定shared_ptr会给您带来什么——很明显,从我对情况的有限理解来看,Doc拥有CDiscreteDistribution对象。拥有其他两种分配的人负责删除它们;这可以通过共享ptr或其他方式完成。(你说“局部实例化”,但这并不意味着什么——它们是在堆或堆栈上实例化的吗?它们的生存期是什么?它们的生存期为什么不同于离散分布对象?什么是“局部”-局部到什么?

    我同意Roel的观点,这个问题没有完全指定。但是,在完成了从原始指针到
    共享\u ptr
    的几次广泛转换之后,我可以给您一些建议

  • 除非您有循环依赖项,否则不必使用
    弱\u ptr
    。换句话说,如果对象A对对象B有一个
    shared_ptr
    ,而对象B对对象A有一个
    shared_ptr
    。在这种情况下,任何一个指针的引用计数都不可能变为0,因此您需要手动干预以打破循环,或者使用
    weak_ptr
    将一方指定为从属
  • 我不明白为什么在使用
    shared\u ptr
    时会出现双重删除问题。一般来说,智能指针的优点之一是不必实际删除它们。如果已将所有原始指针转换为
    共享\u ptr
    ,则不应出现此问题。如果您的
    CConstantDistribution
    CContinuousDistribution
    对象实际上是本地对象,而不是分配给
    new
    (我无法从您的描述中100%判断是否是这种情况),如果您可以更改应用程序的代码,您可以使它们成为在构造函数中初始化的
    共享对象。这将允许您将
    std::vector
    作为
    shared\u ptr
    CDiscreteDistribution
    的容器。此时,您根本不必担心删除这些对象,除非您有如上所述的循环引用。即使您这样做了,您也会将双重删除崩溃转换为内存泄漏,这通常不那么糟糕
  • 序列化可能很困难。因为您已经用MFC标记了这个问题,所以我假设您正在使用MFC序列化。当我序列化到一个文件时,在
    shared\u ptr
    中包装所有内容通常没有问题——我只是在智能指针对象上使用
    .get()
    ,并序列化生成的原始指针。当我在中序列化时,我从序列号中读取原始指针