9

我是 C++ 的新手,有一些问题,这就是其中之一。

当您使用接受一个或多个参数的函数时,是否有任何理由,您知道在函数调用之前将始终存储在变量中的参数传递变量的副本,而不是指向变量的指针?

我说的是性能。在我看来,传递整个结构的副本比仅传递一个指针(4 个字节)需要更多的资源。

4

6 回答 6

12

有几种方法可以使传递副本比传递指针更便宜。

  1. 对象等于或小于指针。直接访问一个值总是比取消引用一个指针要快。
  2. 该结构足够小,可以由编译器放入堆栈。在这种情况下,对结构中的值的访问是通过索引寻址模式而不是间接的索引寻址模式完成的。前者通常更快。

想要传递副本而不是引用还有其他原因,即您的函数将对结构进行更改,这些更改不会反映给调用者。虽然这通常是一种不好的做法,但使参数按值传递将确保调用者的视图不会被错误地更改。

现在对于您可能不想听到的部分答案:它通常不会产生太大的影响!使用对程序语义最有意义的参数传递方法。如果您稍后发现某个特定领域存在性能瓶颈,那么请专注于提高那里的性能。不要过度优化!

于 2008-11-04T11:34:16.267 回答
10

通过指针(或引用)传递对象和传递同一对象的副本具有不同的语义。如果希望对对象所做的更改反映在函数调用之外,则需要引用语义,否则需要值语义。

通常,值语义可以通过按值传递值或通过 const 引用来表示

void value_semantics(my_obj obj);
void value_semantics(const my_obj& obj);

然而, const 引用方式也有一些缺点,它阻止了编译器由于别名问题而可能进行的一些优化,对于具有琐碎构造函数的对象,额外的间接级别(引用被实现为指针)可能超过避免的好处副本。

为了获得引用语义,您可以选择通过引用传递或通过指针传递,因为其他人已经说过引用比 C++ 中的指针更自然(您不必使用 operator 的地址&),并且指针的唯一真正优势是如果要启用 NULL 值。

经验法则是,对于非平凡的类,您应该通过 const 引用传递,否则按值传递。

于 2008-11-04T11:35:32.347 回答
4

指针为错误打开,因为它允许被调用者更改对象。指针可以为 0,这往往会导致崩溃,这需要在所有地方测试 0 指针,这可能很烦人。在可能的情况下使用 C++ 引用const-declared 可以避免这两个问题。

于 2008-11-04T11:25:35.580 回答
4

避免使用指针。如果是 IN 参数,请使用常量引用,否则仅引用 IN OUT 参数

于 2008-11-04T11:31:48.533 回答
2

主要问题不在于性能,而在于语义,以及您的函数是否会修改结构中的数据。

如果您的函数修改了结构,那么传递一个指针将使调用者看到结构中更改的数据。在这种情况下,传递一个副本可能是错误的,因为您的函数将修改一个副本,然后(可能)丢弃该副本。当然,您的函数可能会修改数据,但您不希望修改,在这种情况下,副本是正确的做法,以保护原始值不被更改。

如果您的函数不修改结构,则没有理由复制值,因为它们只会被读取。

如果您对将指针传递给结构的概念不满意,您应该进行一些练习,因为这是在 C 和 C++ 中处理结构的典型方式。

就性能而言,复制结构需要更多的工作,但在方案中它相当小。首先要注意代码的语义。

于 2008-11-04T11:31:00.890 回答
1

引用更常见,如果它们不会更改,则为 const 引用。

于 2008-11-04T11:25:11.323 回答