在c ++中通过指针初始化

时间:2016-08-30 16:07:48

标签: c++ class pointers initialization

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

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

但我也可以这样做:

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

然后使用:

在构造函数中初始化类
animals = new Animals();

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

3 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:1)

如果animals对象的唯一存在取决于MyClass对象,则使用包含

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 same动物`指针。

如果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);

答案 2 :(得分:0)

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

例如,如果你有一只带鸟的笼子,你的第一个笼子总是有一只鸟,它不能没有鸟,但第二个例子你可能有也可能没有鸟。

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

第二个方面是,在第一个示例中,您始终拥有相同的Animal,并且您无法自由传递它,Animal的生命周期完全取决于容器。第二个示例允许将Animal移动到新容器或在两个不同的容器中使用相同的Animal,并将{{1}}的生命与容器分离。

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