【问题标题】:C++ Object Pointers and ScopeC++ 对象指针和范围
【发布时间】:2014-03-26 15:50:19
【问题描述】:

我对 C++ 的 OO 方面比较陌生,所以请原谅这个问题,我认为这个问题比较直截了当;

我有一些代码,大致是这样的

SuperClass* super;

if (useSub1())
{
    SubClass1 sub1 (s);

    super = &sub1;
}
else if (useSub2())
{
    SubClass2 sub2 (s);

    super = &sub2;
}

super.someMethod();

需要注意的是,这里的重点是“sub”的构造取决于调用 someFunction() 的结果。 此外,还会有多个类似上面的 if (...) { } 构造,每个构造都基于 SuperClass 的不同 SubClass,基于某些条件创建不同的 Object。

总而言之,SuperClass 有许多子类,我想根据 if 条件创建适当的对象类型,然后使用“超级”对象来操作它们。

这是我的问题,我认为通过执行我所拥有的 sub1(或 sub2 )将超出范围,那么这是否会给我留下一个指向任何内容的指针?

我希望我想做什么是相当清楚的,我只是不确定如何正确编码。感谢您提供任何帮助或建议。

感谢期待

【问题讨论】:

  • 是的,它会给你留下一个错误的指针。这将是未定义的行为。如果您希望内存超过创建它的范围,则必须使用 new。

标签: c++ pointers scope


【解决方案1】:

根据您问题中的信息了解创建模式:工厂或工厂方法可能适合您的需求。

该设计模式允许在堆中动态创建对象,并且您可以使用指向基类的指针来操作创建的对象。

为防止内存泄漏并正确处理资源,我建议您使用智能指针std::unique_ptr<Type>boost::shared_ptr<Type>
如果您要使用 std::auto_ptr 请勿将其与容器一起使用

【讨论】:

  • 不要使用 std::auto_ptr,而是使用 std::unique_ptr。
  • @const_ref 哦,是的,谢谢。无论如何,熟悉智能指针概念作为资源管理的好工具是很有用的
  • @Daniel Daranas 据我所知 auto_ptr 允许在容器中复制,这可能会导致错误,在这种情况下,unique_ptr 更强大(因为当您复制 auto_ptr/ 时,唯一所有权被转移,您可以留下如果您将 auto_ptr 与诸如 vector 之类的容器一起使用,则悬挂指针)
  • auto_ptr 有一个奇怪的复制行为:a = b 窃取b 的内容并将它们处理给a。这可能不是用户想要做的。
  • 出于好奇......工厂与将原始问题中的代码打包为(工厂)类有何不同?
【解决方案2】:

正如@Ben 所说:使用新的

SuperClass* super;

if (useSub1()) {
    super = new SubClass1(s);
}
else if (useSub2()) {
    super =new SubClass2(s)
}

super->someMethod();

【讨论】:

  • 如果useSub1()useSub2() 都返回false 会怎样
  • 呃...是的,对不起。我只是遵循与原始问题相同的结构。
  • 感谢您的回答,它当然可以完美运行。我一直反对使用新的,因为这需要一些家务来删除它。尽管在这种情况下,这似乎是最好的方法。如果 if 中的条件失败,则除了 cmets 之外,没有“包罗万象”。这只是我想要做的松散的事情,我接受这需要在实际代码中解决。再次感谢
  • 如果您担心分配内存的生命周期,请考虑使用智能指针(正如其他答案中所建议的那样)
  • 智能指针可能确实是另一种方式。我现在已经实施了你最初使用 new 的建议,这让我很感动。感谢您的宝贵时间。
【解决方案3】:

是的,sub1 和 sub2 对象 dtor 将在它们超出范围时被调用,并且“超级”指针将指向处于不确定状态的堆栈中的对象。在某些情况下,它可能仍然在有效的内存区域中,因此不会导致段冲突,从而导致一个微妙的错误。

看起来您还需要类似“抽象工厂”设计模式的东西:

http://en.wikipedia.org/wiki/Abstract_factory_pattern

【讨论】:

    【解决方案4】:

    你可以使用工厂方法:

    std::unique_ptr<SuperClass> create(const std::string& name)
    {
        if (name == "Sub1")
            return std::unique_ptr<SubClass1>{new SubClass1};
    
        if (name == "Sub2")
            return std::unique_ptr<SubClass2>{new SubClass2};
    
        throw std::runtime_error;
    }
    

    这里我使用了std::string 来选择要创建的对象的类型,但也可以使用enum

    注意std::unique_ptr自己管理对象的生命周期,所以不需要delete任何东西。

    void foo()
    {
        auto object = create("SubClass1");
        object->bar();
    } <-- object is deleted automatically
    

    【讨论】:

      猜你喜欢
      • 2015-09-30
      • 2013-10-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 2018-02-23
      相关资源
      最近更新 更多