C++ C++;:常量正确性和指针参数
我知道常量指针可以通过以下几种方式声明:C++ C++;:常量正确性和指针参数,c++,function,pointers,constants,C++,Function,Pointers,Constants,我知道常量指针可以通过以下几种方式声明: const int * intPtr1; // Declares a pointer that cannot be changed. int * const intPtr2; // Declares a pointer whose contents cannot be changed. // EDIT: THE ABOVE CLAIMS ARE INCORRECT, PLEASE READ THE ANSWERS. 但是,在函数参数的上下文中,相同的
const int * intPtr1; // Declares a pointer that cannot be changed.
int * const intPtr2; // Declares a pointer whose contents cannot be changed.
// EDIT: THE ABOVE CLAIMS ARE INCORRECT, PLEASE READ THE ANSWERS.
但是,在函数参数的上下文中,相同的原则又如何呢
我认为以下是多余的:
void someFunc1(const int * arg);
void someFunc2(int * arg);
由于someFunc 1和2对指针本身执行传递值,因此在给定的函数调用中,someFunc 1不可能更改原始指针的值。举例说明:
int i = 5;
int * iPtr = &i;
someFunc1(iPtr); // The value of iPtr is copied in and thus cannot be changed by someFunc1.
如果这些都是真的,那么声明一个带有'const int*ptr'类型arg的函数就没有意义了,对吗?是的,你是正确的(忽略你得到它们的方式是错误的这一事实)-使用非引用的
const
参数是没有意义的。此外,返回非引用的const
值没有意义。这不是针对调用方的,而是针对someFunc1
中的代码。这样someFunc1
中的任何代码都不会意外更改它。像
void someFunc1(int *arg) {
int i = 9;
arg = &i; // here is the issue
int j = *arg;
}
让我们做一些案例研究:
1) 只是让点的值保持不变
void someFunc1(const int * arg) {
int i = 9;
*arg = i; // <- compiler error as pointed value is const
}
void someFunc1(常量int*arg){
int i=9;
*arg=i;//您的逻辑搞错了。您应该向后读取类型,因此const int*
是指向const int
的指针,int*const
是指向int的const
指针
例如:
void foo() {
int a = 0;
int b = 0;
int * const ptrA = &a;
*ptrA = 1;
ptrA = &b; ///< Error
const int * ptrB = &a;
*ptrB = 1; ///< Error
ptrB = &b;
const int * const ptrC = &a;
*ptrC = 1; ///< Error
ptrC = &a; ///< Error
}
你把它倒过来:
const int * intPtr1; // Declares a pointer whose contents cannot be changed.
int * const intPtr2; // Declares a pointer that cannot be changed.
以下const
确实是不必要的,没有理由将其放在函数声明中:
但是,您可能希望将其放在函数实现中,原因与您可能希望声明局部变量(或其他任何内容)的原因相同const
-当您知道某些事情不会改变时,实现可能会更容易遵循。无论是否在函数的任何其他声明中声明了const
,您都可以这样做。您使用了错误的方法:
const int * intPtr1; // Declares a pointer whose contents cannot be changed.
int * const intPtr2; // Declares a pointer that cannot be changed.
一般来说,编写稍微不同的表达式时,更容易对常量进行推理:const int*
与int const*
的类型相同。在这种表示法中,规则更加明确,const
始终适用于它前面的类型,因此:
int const * intPtr1; // Declares a pointer to const int.
int * const intPtr2; // Declares a const pointer to int.
int const * * const * complexPtr; // A pointer to const pointer to pointer to const int
当使用前导的const
写入类型时,const
的处理方式与在第一个类型之后写入的方式相同,因此const T*
变为T const*
void someFunc2(int * arg);
因此不是多余的,因为someFunc2
可能会更改arg
的内容,而someFunc1
可能不会更改。void someFunc3(int*const-arg);
将是多余的(和模糊的),尽管您的声明是错误的。“const-int*”是指向不可更改的int的可变指针。“int*const"是一个指向可变整数的不可更改指针。编辑该问题是为了让喜欢触发的Google用户不会得到错误信息。我留下了错误,以便答案仍然有上下文。非引用const
返回值甚至有害。@Xeo:请详细说明一下,好吗?我根本不知道它们有任何影响!@ruakh:看,这是一个相当小的问题。@ruakh:移动语义就是其中之一。T const&&
不能从中移动,即使你知道它是一个临时的,很快就会被销毁。@ruakh:那篇文章是十多年前写的,所以是的,在移动语义建立之前很久。但这并不能解释为什么你要写void someFunc1(常量int*arg);
。请注意,将someFunc1
预声明为void someFunc1(int*arg);
仍允许您将其定义为void someFunc1(int*const arg){…}
如果需要,参数变量本身的常数不会影响实际的函数签名。@ruakh请检查更新后的ans。这应该是您的问题。对不起,不,您的更新后的答案仍然没有回答问题。(有关正确答案,请参阅上面Mike Seymour的答案。)“但是,您可能希望将其放在函数实现中,原因与您可能希望声明一个局部变量(或任何其他)const”=“我已经提到过它是用于函数代码而不是用于调用方的"…无论如何,这一点很清楚,这就是底线…我想我只是对回答这个问题的答案有一种奇怪的偏好!现在我看起来像个傻瓜…感谢你的简明解释,并确认其中一个定义中确实存在不必要的常量。const int*intPtr1
和int-const*intPtr1;
?@yes123:没有区别。const
限定前面的东西,除非它在开头,在这种情况下它限定第一件事。所以在这两种情况下,它限定int
,而不是指针。int-const
将限定指针。@MikeSeymour:哇,这太清楚了,我想知道有什么问题问这个?(我发现这个问题可以通过你的评论来解决。)常见技巧:从右到左读取任何c类声明:int-const*intPtr1
-->intPtr1
是指向常量(只读)整数的指针
void someFunc1(int * const arg);
const int * intPtr1; // Declares a pointer whose contents cannot be changed.
int * const intPtr2; // Declares a pointer that cannot be changed.
int const * intPtr1; // Declares a pointer to const int.
int * const intPtr2; // Declares a const pointer to int.
int const * * const * complexPtr; // A pointer to const pointer to pointer to const int
void someFunc2(int * arg);