c++中通过指针初始化
Initializing by pointer in c++
假设我有一个类MyClass
。现在我想使用另一个类Animals
,我可能会这样做。
class MyClass
{
public:
MyClass();
private:
Animals animals;
};
但是我也可以这样做:
class MyClass
{
public:
MyClass();
private:
Animals* animals;
};
,然后在构造函数中初始化类:
animals = new Animals();
这两种不同的方法有什么不同,哪一种更好,为什么?在我的使用中,Animals
只能在MyClass
中使用。我的问题主要是关于性能和内存,我的意思是通过指针初始化是否需要更多的资源?
如果您考虑如何在类中管理内存,那么应该很清楚。当您在类中声明Animals animal
时,则在类的内存占用中为animal
保留空间。但是当你声明Animals* animal
时,在你的类的内存占用中只保留一个指向Animal
的指针。
都不是更好的,因为这取决于你的情况。如果您总是要创建一个动物并且MyClass
拥有它,那么使用第一种方法,因为它只需要一个内存分配。如果animals
经常是空的,并且内存是一个问题,那么您可能需要使用第二种方法。
顺便说一下,如果您使用的是c++ 11或以上版本,您可能需要考虑使用std::unique_ptr<Animal>
作为第二种情况。
如果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);
从设计的角度来看,MyClass
是一个Animal
的容器。在第一个例子中,您总是有一个Animal
。在第二个示例中,您可能有也可能没有Animal
。
例如,如果你有一只鸟的笼子,你的第一个笼子里总是有一只鸟,它不能空着,但第二个例子你可能有也可能没有鸟。
在数据库中称为Cardinality
(0,1)。您可以将其想象为具有一个或零个元素的Animals
的集合(即使您没有数组)。
第二个方面是,在第一个例子中,你总是有相同的Animal
,你不能自由地传递它,Animal
的生命周期完全取决于容器。第二个示例允许将Animal
移动到一个新的容器中,或者将相同的Animal
放在两个不同的容器中,并将Animal
的生命周期与容器解耦。
然后,在c++中,你必须考虑内存分配和所有权,我们通常使用智能指针来释放Animal.
- 如何使用数据对象上的常量指针初始化类
- 使用指针初始化 char 数组或字符串 C++
- 使用无效指针初始化指针声明符的行为是否未定义?
- 指针:初始化与声明
- 启动线程会导致指针初始化时出现分段错误
- 使用函数声明进行函数指针初始化 - 是否可能
- 类初始化中的指针初始化
- 结构数组的指针初始化
- 如何从其抽象母类上的指针初始化子类?
- C 用结构指针初始化结构
- 如何用无效指针初始化unique_ptr的向量
- PCL中的这些增强指针初始化是不同的
- 通过指针初始化结构
- 从函数指针初始化成员函数
- 使用作用域内生成的指针初始化静态成员
- 使用"this"指针初始化 std::array
- C++缺乏指针初始化和使用逻辑
- constexpr 使用指针初始化
- C 指针初始化的不良初始化可能是什么后果
- 指针初始化无效?如果不是,那是什么