注意:我知道有很多问题都在讨论,但我还是初学者,我无法理解这些例子。
我得到了一个像这样的函数原型:
int someFunction(const char * sm);
如您所知,const char *表示此函数可以接受const或非const指针到char。我在函数体中尝试了类似的东西:
someMemberVar = sm;
someMemberVar只是一个指向char的指针。编译器给我一个错误告诉我: 无法从const char *转换为char *。
这里,我没有传递常量,所以sm或someMemberVar都不是常量。那么,编译器正在讨论什么常量?
答案 0 :(得分:11)
我会尝试简单地说出其他人在说什么:
函数someFunction
采用只读字符串(为简单起见,尽管char *
可以在其他情况下使用)。无论是否将只读字符串传递给someFunction
,该参数在此函数的上下文中执行的代码都被视为只读。因此,在此函数中,编译器将尽可能地阻止您写入此字符串。非const指针是这样一种尝试忽略对字符串和编译器的只读标记,正确而大声地通知你这种类型系统的无视;)
有什么区别:int someFunction(const char * sm)const {...}和this:int someFunction(const char * sm){...}
第一个是一个带有readonly参数的函数。在右括号后写的第二个const
仅对成员函数有效。它不仅需要一个只读参数,还需要保证不改变对象的状态。这通常称为设计级别const。
答案 1 :(得分:10)
您的问题并不完全清楚,我怀疑您提供的错误文本实际上是错误的,实际上是:
无法从
const char*
转换为char*
既然你说
someMemberVar只是一个指向char的指针。
这是有道理的。请记住,const char*
实际上与char const*
相同 - 也就是说,它是指向const char的指针,而不是指向char的const指针!并且您无法将指向T const
的指针转换为指向T
的指针,因为这会破坏类型安全性。考虑:
const char* a = "abc";
char* b = a; // what you're trying to do
b[0] = 'x'; // if you could do it, you could change const data without casts
答案 2 :(得分:4)
const char*
是指向常量char:
const char* ptr0; // ptr0 is mutable, *ptr0 is const
char* const ptr1; // ptr1 is const, *ptr1 is mutable
答案 3 :(得分:1)
如果将非const指针传递给someFunction
,它会自动转换为const指针。因此,您无法将sm
分配给someMemberVar
,因为这会违反sm的常量。您可以将someMemberVar
声明为const char*
并且您的代码可以正常工作,但是,您无法修改它所指向的内容。
答案 4 :(得分:1)
在其他一个答案的评论中,您说:
const char * sm意味着我可以传递一个 const或非const,那么为什么是C ++ 自动转换?那 对我来说没有意义。
在您的原始问题与该评论之间,我认为您误解了编译器如何处理这些类型。
你是正确的,非const char *
可以安全地转换为const char *
。但是,您的方法明确采用const char *
。因此,虽然您可以将char *
传递给函数,但编译器只是在进行函数调用时自动转换参数。函数中的实际代码不知道原始参数是否为const。编译器必须通过您正在使用的变量的实际声明,不一些具有相同值的先前变量。
如果您希望能够以不同方式处理非常量char *
变量(分配它们),那么您需要定义一个带有非常量char *
变量的函数。
答案 5 :(得分:0)
const char * sm是指向常量字符(或数组)的指针。当您尝试分配 someMemberVar (指向char的指针)时,您试图将其指向一组常量字符。这是导致错误的原因。
答案 6 :(得分:0)
在你的例子中,sm是const char *所以someFunction与它的调用者有一个契约,它不会修改sm指向的内存。
但是如果你将sm分配给someMemberVar并且someMemberVar不是const char *,那么你将能够通过someMemberVar修改sm指向的内存,并且编译器不允许你这样做。