C++实例 VS 指针 VS 引用

C++ Instances VS pointers VS references

本文关键字:VS 引用 指针 C++ 实例      更新时间:2023-10-16

我有一个程序,它创建了我自己的类的许多实例。然后作它们:读取,更改,将它们传递给一些第三方方法等。

有三个问题。

  1. 我存储的是实例向量还是指针向量?为什么?

  2. 如果我不想更改实例,我是否应该向函数传递实例或指向它的指针?为什么?

  3. 如果我确实要更改实例,是传递指针还是引用?为什么?

提前感谢!

类示例:

class Player {
    public:
        static const char               width = 35;
        static const char               height = 5;
        static const char               speed = 15;
        int                             socketFD;
        float                           xMin;
        float                           xMax;
        char                            status;
        float                           x;
        float                           y;
        char                            direction;
                                        Player ( int );
        void                            Reset();
        void                            Move();
        void                            SetHost();
        void                            SetClient();
    private:
        void                            EscapeCheck();
};

是存储实例数组还是指针数组?为什么?

如果Class是基类,并且您希望防止对象切片,则存储指针。否则,对象。

如果我不想更改实例,我是否应该向函数传递实例或指向它的指针?为什么?

如果按值传递,则不会修改原始对象,因为您正在处理副本。如果传递指针或引用,则将其标记为 const:

void foo ( MyClass const* );
void foo ( MyClass const& );

如果我确实要更改实例,是传递指针还是引用?为什么?

也。我个人更喜欢引用,指针与动态分配的联系更紧密。

如今,经常使用 RAII,因此一个很好的选择是使用智能指针。

是存储实例数组还是指针数组?为什么?

这实际上取决于用例。任一解决方案都可以,具体取决于上下文。您可能希望存储多态类型的基类,或者您可能希望避免复制元素(例如,在处理不可复制类型时)。在这些情况下,应存储指针或智能指针。

如果我不想更改实例,我是否应该向函数传递实例或指向它的指针?为什么?

然后你应该传递一个常量引用(对常量实例的引用)

void foo(const Foo& f);

如果我确实要更改实例,是传递指针还是引用?为什么?

然后,您应该传递一个非常量引用(对非常量实例的引用)。这假设您确实想要更改现有实例:

void foo(Foo& f);

但是你什么时候会使用指针呢?那么我现在能想到的唯一情况是传递的实体有可能具有无效或空值。有了参考,这是不可能的,或者至少实现起来不容易。指针可以设置为 0NULL(相同)或 C++11 中的nullptr

void (Foo* f) {
  if (f) {
    // do something with pointee
  } else {
    // deal with it
  }
}

是存储实例数组还是指针数组?为什么?

如果您的对象很大(即超过 2-3 个基元类型),则需要存储指向动态分配实例的指针数组。这将使重新排序对象和调整容器大小/重新分配容器的速度更快。如果要使用多态性,则几乎必须使用指向基类的指针(请注意,引用也是多态的)。这将防止切片,因为数组的所有元素必须具有相同的大小,因此如果要存储多个对象,指向基类的指针是可行的方法。

您可能更喜欢将实例存储在容器中的情况是,如果您具有单个类型(没有继承和多态性)并且它不是那么大(即几个基元成员类型)。对于较大的对象,您可能希望使用链表而不是数组,以避免代价高昂的插入和重新分配。

如果我不想更改实例,我是否将 实例或指向它的指针?为什么?

传递指向常量对象或常量引用的指针。除非您传递基元,否则您可以简单地传递便宜的副本并避免修改原始对象。无论是指向 const 对象的指针还是指向 const 引用取决于您的使用方案,引用都更容易使用,就像普通实例一样,但不能像指针那样更改为对其他对象的引用。

如果我确实想更改实例,是传递指针还是 参考?为什么?

如果要更改实例,请传递指针或引用。两者中的哪一个 - 见上文。这样,您可以直接修改特定实例。您也可以按值传递,但它将创建一个临时副本,稍后需要将其分配回原始对象。这样做是没有意义的,如果修改是你的意图,请始终寻求指针或参考。即使您不打算修改对象,传递常量指针或引用仍然便宜得多,因为它们是 int 的大小,而对象可能要大得多,因此复制它没有意义。如果要传递基元类型,则不妨按值传递,尽管如果您打算修改对象,则仍然有一个可以避免的额外赋值。

对于第二,这取决于。最有效的方法可能是传递常量引用。

一般来说,尽量避免指针。如果必须使用指针,请使用智能指针。

  1. 实例数组更好,因为您可以保存在指针本身和分配块标头上。(前提是该阵列可以满足您的需求)。

2,3 在这两种情况下,最好通过引用。在第二种情况下,常量参考。优点是无需调用 ctors。

是存储实例数组还是指针数组?为什么?

我更喜欢使用实例数组。管理记忆将减少头痛。如果你动态填充指针数组,你可能会在第 1000 个元素处捕获 OOM - 现在程序必须清理半格式数组。从这个意义上说,最好一次性预分配一大块。

如果我不想更改实例,我是否应该向函数传递实例或指向它的指针?为什么? 如果我确实要更改实例,是传递指针还是引用?为什么?

我总是更喜欢参考文献,因为这样您就可以跳过检查其有效性。维基百科说引用不能是 NULL,但我可以到处踢 NULL 引用,因为行为是未定义的,在我的编译器中恰好是这样。但如果你考虑到这一点,你真的处于权力的黑暗面。或者,声明函数以接受指针邀请以传递NULL并且您必须始终检查它。有一个很好的博客描述了空引用 - 很好的例子改变了我的想法。

使用引用的一个缺点是,你不能从函数调用代码行中说出函数是按值还是按引用接受参数。

您应该记住,引用本质上是指针,引用类型具有大小,因此,如果您的Class非常小,那么如果您不想在函数中更改对象,则可以考虑按值传递对象。不过,我仍然会通过引用 - Class可以增长,然后你去修复所有原型 - 不好。