【问题标题】:Initializing by pointer in c++ [closed]在c ++中通过指针初始化[关闭]
【发布时间】:2016-08-30 16:07:48
【问题描述】:

假设我有一个班级MyClass。现在我想使用另一个名为Animals 的类,我可能会执行以下操作。

class MyClass
{
public:
    MyClass();
private:
    Animals animals;
};

但是我也可以这样做:

class MyClass
{
public:
    MyClass();
private:
    Animals* animals;
};

然后在构造函数中初始化类:

animals = new Animals();

这两种不同的方法有什么区别,哪个更好,为什么?在我的使用中,Animals 只能在 MyClass 内部使用。我的问题主要是关于性能内存,我的意思是指针初始化是否需要更多资源?

【问题讨论】:

  • 这听起来像是一道作业题。你能把你的问题具体说明一下吗
  • 看来你需要阅读this
  • @TankorSmash 这不是作业问题,但我会努力改进我的问题
  • 也许您可以尝试指定您希望如何使用动物作为指针或其他东西,并通过这样做来解释您遇到的问题。现在它是如此广泛,很难有效地回答。
  • 使用new 分配给你一个指向在堆上创建的对象的指针。第一种方法预先分配内存作为父结构的一部分。如果您通过new 分配内存,您必须最终释放该内存。

标签: c++ class pointers initialization


【解决方案1】:

如果您考虑如何在一个类中管理内存,它应该会变得清晰。当您在类中声明 Animals animal 时,会在类的内存占用中为 animal 保留空间。但是当你声明 Animals* animal 时,只有一个指向 Animal 的指针会保留在你的类的内存占用中。

两者都不是更好,因为这取决于您的情况。如果你总是要创建一个动物并且MyClass 拥有它,那么使用第一种方法,因为它只需要一个内存分配。如果animals 经常为空并且内存是一个问题,那么您可能需要使用第二种方法。

顺便说一句,如果您使用的是 C++11 或更高版本,您可能需要考虑 std::unique_ptr<Animal> 用于第二种情况。

【讨论】:

    【解决方案2】:

    如果animals对象的唯一存在依赖于MyClass对象,那么使用containment

    class MyClass
    {
    public:
        MyClass();
    private:
        Animals animals;
    };
    

    如果animals的存在是独立的,但MyClass想保持与之关联,则使用指针

    class MyClass
    {
    public:
        MyClass();
    private:
        Animals * animals;
    };
    

    选择取决于对象所有权模型。

    涉及到许多考虑因素。

    在包含方法中,animals 的内存与MyClass 对象一起分配。他们总是在一起,MyClass 完全拥有 animals

    在指针方式中,它们是两块独立的内存,需要分别分配。这是一个没有任何所有权的协会。在MyClass 的整个生命周期中,可能会发生多种情况:

    • myclass 不与任何Animals 关联,即animals = nullptr
    • myclass可能在不同的时间关联到不同的Animals,即animals = a1; /* ... */; animals = a2;

    此外还有多个对象,MyClass 对象或其他类型的对象, may hold the sameanimals` 指针。

    如果animals 对象被销毁,那么这些对象就有使用过时指针的风险,因此需要一些机制来避免这种情况。

    使用指针方法,可以使用在包含方法中不可能的运行时多态性。例如

    void MyClass::setAnimal(Animal * a) {
      animal = a;
    }
    
    Animal * a1 = new Lion;
    Animal * a2 = new Tiger;
    
    MyClass x1;
    x1.setAnimal(a1);
    
    MyClass x2;
    x2.setAnimal(a2);
    

    【讨论】:

      【解决方案3】:

      从设计的角度来看,MyClass 是一个Animal 的容器。在第一个示例中,您总是有一个Animal。在第二个示例中,您可能有也可能没有Animal

      例如,如果您的笼子里有一只鸟,那么您的第一个笼子总是有一只鸟,并且不能没有鸟,但第二个例子您可能有鸟,也可能没有鸟。

      这在数据库中称为Cardinality (0, 1)。你可以把它想象成有一个Animals 的集合,有一个或零个元素(即使你没有数组也很难)。

      第二个方面是,在第一个示例中,您始终拥有相同的Animal,并且您不能随意传递它,Animal 的生命周期完全取决于容器。第二个示例允许将Animal 移动到新容器或在两个不同的容器中拥有相同的Animal,并将Animal 的生命周期与容器解耦。

      然后,在 C++ 中,您必须考虑内存分配和所有权,我们通常使用智能指针来释放 Animal。

      【讨论】:

        猜你喜欢
        • 2023-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-22
        • 2022-01-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多