何时在函数args中使用const和const引用?

时间:2010-10-19 09:57:52

标签: c++ arguments const

当编写一个带有传递给它的args的C ++函数时,如果可以保证对象不会被更改,那么应该总是使用const,如果指针不会被更改,则应该使用const指针。

这种做法何时建议?

你何时会使用const引用,比仅通过指针传递它有什么优势呢?

这个怎么样void MyObject::Somefunc(const std::string& mystring)如果一个字符串实际上已经是一个不可变对象,那么拥有一个const字符串会有什么意义呢?

4 个答案:

答案 0 :(得分:39)

不幸的是,询问是否添加const是错误的问题,

将非常量引用与传递非常量指针

进行比较
void modifies(T &param);
void modifies(T *param);

这种情况主要与风格有关:您希望通话看起来像call(obj)还是call(&obj)?但是,差异有两点重要。如果您希望能够传递null,则必须使用指针。如果你正在重载运算符,则不能使用指针。

将const ref与值

进行比较
void doesnt_modify(T const &param);
void doesnt_modify(T param);

这是一个有趣的案例。经验法则是“便宜复制”类型是通过值传递的 - 这些通常是小类型(但并非总是) - 而其他类型则由const ref传递。但是,如果您需要在函数中制作副本,则should pass by value。 (是的,这暴露了一些实现细节。 C'est le C ++。

将const指针与非修改加上重载

进行比较
void optional(T const *param=0);
// vs
void optional();
void optional(T const &param); // or optional(T param)

这与上面的非修改情况有关,除了传递参数是可选的。这三种情况之间的差异最小,因此请选择最适合您生活的方式。当然,非const指针的默认值取决于你。

Const by value是一个实现细节

void f(T);
void f(T const);

这些声明实际上是完全相同的函数!当通过值传递时,const纯粹是一个实现细节。 Try it out:

void f(int);
void f(int const) {/*implements above function, not an overload*/}

typedef void C(int const);
typedef void NC(int);
NC *nc = &f;  // nc is a function pointer
C *c = nc;  // C and NC are identical types

答案 1 :(得分:4)

一般规则是,尽可能使用const,并在必要时仅省略它。 const可以使编译器能够优化并帮助您的同行理解您的代码的使用方式(编译器将捕获可能的误用)。

至于你的例子,字符串在C ++中不是不可变的。如果将对字符串的非const引用传递给函数,则该函数可以对其进行修改。 C ++没有内置于语言中的不变性概念,你只能使用封装和const来模拟它(尽管它永远不会是防弹的。)

在考虑@Eamons评论并阅读一些内容之后,我同意优化不是使用const的主要原因。主要原因是拥有正确的代码。

答案 2 :(得分:3)

这些问题是基于一些不正确的假设,所以没有多大意义。

std::string不会为不可变字符串值建模。它模拟可变值。

没有“const引用”这样的东西。有const个对象的引用。区别是微妙但重要的。

函数参数的顶级const仅对函数实现有意义,而不是纯语句(编译器忽略它)。它没有告诉来电者什么。这只是对实施的限制。例如。 int const作为函数的纯声明中的参数类型几乎没有意义。但是,const中的std::string const&不是顶级。

通过引用传递const可以避免低效复制数据。通常,对于将数据传递到函数的参数,您可以按值传递小项(例如int),并通过引用const传递更大的项。在机器代码中,可以优化对const的引用,或者可以将其实现为指针。例如,在32位Windows中,int是4个字节,指针是4个字节。因此参数类型int const&不会减少数据复制,但是可以通过简单的编译器引入额外的间接,这意味着效率很低 - 因此小/大区别。

干杯&第h。,

答案 3 :(得分:0)

const引用优于const指针的主要优点如下:它清楚表明该参数是必需的,不能为NULL。 反之亦然,如果我看到一个const指针,我会立即假设它不是参考的原因是参数可能是NULL。