当编写一个带有传递给它的args的C ++函数时,如果可以保证对象不会被更改,那么应该总是使用const,如果指针不会被更改,则应该使用const指针。
这种做法何时建议?
你何时会使用const引用,比仅通过指针传递它有什么优势呢?
这个怎么样void MyObject::Somefunc(const std::string& mystring)
如果一个字符串实际上已经是一个不可变对象,那么拥有一个const字符串会有什么意义呢?
答案 0 :(得分:39)
不幸的是,询问是否添加const是错误的问题,。
void modifies(T ¶m);
void modifies(T *param);
这种情况主要与风格有关:您希望通话看起来像call(obj)
还是call(&obj)
?但是,差异有两点重要。如果您希望能够传递null,则必须使用指针。如果你正在重载运算符,则不能使用指针。
void doesnt_modify(T const ¶m);
void doesnt_modify(T param);
这是一个有趣的案例。经验法则是“便宜复制”类型是通过值传递的 - 这些通常是小类型(但并非总是) - 而其他类型则由const ref传递。但是,如果您需要在函数中制作副本,则should pass by value。 (是的,这暴露了一些实现细节。 C'est le C ++。)
void optional(T const *param=0);
// vs
void optional();
void optional(T const ¶m); // or optional(T param)
这与上面的非修改情况有关,除了传递参数是可选的。这三种情况之间的差异最小,因此请选择最适合您生活的方式。当然,非const指针的默认值取决于你。
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。