const char *作为C ++中的函数参数

时间:2009-10-30 20:30:59

标签: c++ const

注意:我知道有很多问题都在讨论,但我还是初学者,我无法理解这些例子。

我得到了一个像这样的函数原型:

int someFunction(const char * sm);

如您所知,const char *表示此函数可以接受const或非const指针到char。我在函数体中尝试了类似的东西:

someMemberVar = sm;

someMemberVar只是一个指向char的指针。编译器给我一个错误告诉我: 无法从const char *转换为char *。

这里,我没有传递常量,所以sm或someMemberVar都不是常量。那么,编译器正在讨论什么常量?

7 个答案:

答案 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指向的内存,并且编译器不允许你这样做。

相关问题