【问题标题】:const char * as a function parameter in C++const char * 作为 C++ 中的函数参数
【发布时间】:2009-10-30 20:30:59
【问题描述】:

注意:我知道有很多问题都在讨论这个问题,但我还是个初学者,看不懂这些例子。

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

int someFunction(const char * sm);

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

someMemberVar = sm;

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

在这里,我没有传递常量,因此 sm 或 someMemberVar 都不是常量。那么,编译器在说什么常量呢?

【问题讨论】:

  • someMemberVar 究竟是如何声明的,你得到的确切错误信息是什么(你提供的错误信息没有任何意义,所以我怀疑那里有错字)。跨度>
  • 我修正了我的错误。它是这样声明的:char * someMemberVar;
  • @Alan 他基本上是正确的。 char* 可以安全地转换为 const char*,因此您可以像传递 const char* 一样将 char* 传递给该方法。编译器只会为你做演员。
  • @Alan:不,它可以接受 const char * 或 char *。它会将它们视为 const char *。您需要显式转换才能将 const 数据类型更改为非 const 数据类型,而不是另一种方式。毕竟,仅仅因为一个变量可以被写入并不意味着我必须改变它的值。
  • 虽然出于其他原因您需要了解此处发生的情况,但您可能想要的真正解决方案是将someMemberVar 设置为std::string。尤其是当您学习语言的基础知识时,保存值的变量(如 int、string 等)更易于使用。在你学会了这门语言之后,它们仍然更容易使用(因为你/想要/大部分时间都持有一个值)。

标签: c++ constants


【解决方案1】:

我会尝试用更简单的术语来表达其他人所说的话:

函数someFunction 采用只读字符串(为简单起见,尽管char * 可用于许多其他情况)。无论您是否将只读字符串传递给someFunction,在此函数的上下文中执行的代码都会将该参数视为只读的。因此,在这个函数中,编译器会尽可能地阻止你写入这个字符串。非常量指针是一种忽略字符串和编译器的只读标记的尝试,正确而响亮地告诉您这种对其类型系统的忽略;)

int someFunction(const char * sm) const{...} 和 this: int someFunction(const char * sm){...} 有什么区别

第一个是一个带有只读参数的函数。右括号后写的第二个const 仅对成员函数有效。它不仅接受一个只读参数,而且保证不改变对象的状态。这通常称为设计级别常量。

【讨论】:

  • 没关系。有什么区别: int someFunction(const char * sm) const{...} 和 this: int someFunction(const char * sm){...}
  • int someFunction(const char * sm) const{...} 这里的 const 是指我根本不会改变这里的任何数据,还是指参数?
  • 描述“尾随const”的简单方法是它适用于this。在T 类的非常量方法中,this 的类型是T* const。在同一个类的一个const方法中,this的类型是T const* const
【解决方案2】:

你的问题并不完全清楚,我怀疑你给出的错误文本实际上是错误的,实际上是:

无法从 const char* 转换为 char*

既然你这么说

someMemberVar 只是一个指向字符的指针。

这是有道理的。请记住,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

【讨论】:

    【解决方案3】:

    const char* 是一个指向常量字符的指针:

    
    const char* ptr0; // ptr0 is mutable, *ptr0 is const
    char* const ptr1; // ptr1 is const, *ptr1 is mutable
    

    【讨论】:

      【解决方案4】:

      如果您将非常量指针传递给someFunction,它会自动转换为常量指针。所以你不能将sm 分配给someMemberVar,因为这会违反sm 的常量性。您可以将 someMemberVar 声明为 const char* 并且您的代码可以工作,但是您不能修改它所指向的内容。

      【讨论】:

      • const char * sm 表示我可以传递一个 const 或 non-const,那么为什么 C++ 会自动转换呢?这对我来说没有意义。
      • "const char* sm" 表示“指向 const char 的指针”。没有其他的。这就是 sm 在 someFunction 中的作用。您可以将“char*”传递给 someFunction,因为允许从非 const 转换为 const。不允许删除 constness,这是您将 sm 分配给 someMemberVar 时尝试做的事情。
      • 在函数内部,指针被转换,因为您希望它在该函数内部是 const - 您以这种方式声明它。这是该函数与其调用者签订的合同的一部分。如果函数不想保证 sm 指向的内存不会改变,那么不要将参数设为 const char*。
      【解决方案5】:

      在您所说的其他答案之一的评论中:

      const char * sm 表示我可以通过 const 或 non-const,那么为什么是 C++ 会自动转换吗?那 对我来说没有意义。

      在您的原始问题和该评论之间,我认为您误解了编译器如何处理类型。

      您是正确的,非常量 char * 可以安全地转换为 const char *。但是,您的方法明确采用const char *。因此,虽然您可以将char * 传递给函数,但编译器只是在进行函数调用时自动转换参数。函数中的实际代码不知道原始参数是否为 const。编译器必须根据您正在使用的变量的实际声明,而不是一些先前具有相同值的变量。

      如果您希望能够以不同的方式处理非常量 char * 变量(分配它们),那么您需要定义一个接受非常量 char * 变量的函数。

      【讨论】:

        【解决方案6】:

        const char * sm 是一个指向常量字符(或数组)的指针。当您尝试分配 someMemberVar 一个指向字符的指针时,您是在尝试将其指向一组 constant 字符。这是错误的原因。

        【讨论】:

          【解决方案7】:

          在你的例子中 sm 是 const char* 所以 someFunction 与它的调用者有一个合同,它不会修改 sm 指向的内存。

          但是,如果您将 sm 分配给 someMemberVar 并且 someMemberVar 不是 const char*,那么您将能够通过 someMemberVar 修改 sm 指向的内存,而编译器不允许您这样做。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-07-13
            • 1970-01-01
            • 2010-09-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多