Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 修改对作为方法参数传入的const char*的引用有意义吗?_C++ - Fatal编程技术网

C++ 修改对作为方法参数传入的const char*的引用有意义吗?

C++ 修改对作为方法参数传入的const char*的引用有意义吗?,c++,C++,假设我有一些大致如下的东西: int main() { const char* someString = "Hello"; MyClass myClass; myClass.modifySomeString(someString); return 0; } 以及modifySomeString的两个可能的方法签名: 案例Avoid MyClass::modifySomeString(const char*inBuffer) 这看起来毫无意义,因为我会得到一个

假设我有一些大致如下的东西:

int main()
{
    const char* someString = "Hello";

    MyClass myClass;
    myClass.modifySomeString(someString);

    return 0;
}
以及
modifySomeString
的两个可能的方法签名:

案例A
void MyClass::modifySomeString(const char*inBuffer)

这看起来毫无意义,因为我会得到一个值,所以无论我对inBuffer做什么,都不会影响
main()
中的原始someString,对吗

案例B
void MyClass::modifySomeString(const char*&inBuffer)

在这里,我有一个指针的引用,因此我可以实际修改main()中的原始“字符串”(为了清楚起见,可能应该调用参数inOutBuffer…)。但除了我可以强制转换以删除常量并修改方法中的实际参数之外。。。这不是一件坏事吗

我的意思是:

  • someString在main中声明为const,因此尝试将其传递给方法以进行修改是毫无意义的
  • 在方法内部,如果我声明参数也是const,那么再次尝试绕过它的const来修改它会影响main中的某个字符串似乎是错误的
  • 我对案例A和案例B的观察是否正确?或者,将常量字符串传递给方法并期望该方法仍然修改原始字符串是否有合理的原因

    就我个人而言,我认为如果我将一个常量传递给该方法,那么该方法应该有一个out参数,在这里我可以得到一个新字符串,而不改变原始字符串。比如:

    void MyClass::modifySomeString(const char* inBuffer, char*& outBuffer)
    

    但我感兴趣的是一些建议或解释为什么修改const参数非常好的人。

    你不应该创建一个编辑变量的函数,尤其是当它是常量时。您认为它应该创建一个新字符串是正确的。

    否。将参数设置为常量的意义在于您承诺不修改它。根据编译器的不同,可能会禁止您这样做,而不仅仅是发出警告。

    在情况A中,您不会得到字符串的副本,而只是得到指针的副本。你是对的,这是毫无意义的,因为你不能更改字符(除了使用
    const_cast
    ,你不应该使用它),而且对指针本身的更改不会被调用方看到

    但是,在案例B中,您有一个对调用方指针变量的引用。您不能修改它当前指向的字符串,但可以将其重新指定为指向一个完全不同的字符串,当函数返回时,调用方将通过变量看到该不同的字符串。也就是说,在某种意义上,从调用方的角度“修改”字符串


    这可能是一件合法的事情,但也有点奇怪,您需要非常小心内存泄漏。当您为旧字符串分配不同的地址时,请确保不会导致调用者丢失其唯一指向该字符串的指针。

    修改声明为常量的任何变量是未定义的行为。这意味着如果您使用
    char*mutable\u ptr=const\u cast(someString)
    然后通过
    mutable_ptr
    修改
    someString
    ,结果未定义。它可能会改变值,也可能什么都不做,您的程序可能会崩溃,或者编译器可能会用调用
    format_hard_drive()来替换整个内容

    使用
    const\u cast
    修改作为
    const
    传入的内容唯一安全的方法是,如果您知道该值实际上没有声明
    const
    。例如:

    void foo (char const * ptr) {
        // do something with a const_cast on ptr
    }
    int main () {
        char bar [] = "Cool!";
        foo (bar);
        return 0;
    }
    
    bar
    未声明
    const
    ,因此可以安全地在
    foo
    中去掉const限定符。然而,这样做几乎总是表明设计拙劣。如果需要修改传递到函数中的变量,则在不使用
    const
    限定符的情况下声明引用


    这是C++,所有常用语句使用<代码> STD::String 而不是<代码> char const */COD>应用。确切地在我在main()中显示的代码中,初始化原始字符串时只有一个对它的引用。因此,如果我的方法是将指针重新分配到不同的内存地址,那么在返回时,调用方会将其字符串视为“已更改”,但同时也丢失了指向原始地址的唯一指针,而原始地址现在已泄漏。因此,最明智的做法似乎是,正如我所说,要让签名包含第二个参数,通过该参数返回新分配的字符串修改版本,对吗?通常,您会使用返回值,而不是引用参数。但是无论如何,是的,您应该以某种方式将新字符串传递回调用方,而不是替换指向旧字符串的指针。是的,在这种情况下,我会通过方法中的返回值返回新字符串,但我被迫在签名中返回空值。现在。。关于这一点:假设原始字符串仍然像在main()示例中一样声明为const char*,但是现在让我们假设我的方法签名不包括const。也就是说,它看起来与案例B相同,但参数中没有“const”限定符。然后,如果该方法更改了原始值,那么它将是“合法的”,并且当签名明确显示没有常量时,调用方将因传入常量而受到“谴责”?调用方将无法将

    常量char*
    传递给接受
    char*
    的函数。(除非调用者使用类似于
    const_cast
    的东西将其塞入,在这种情况下,如果出现问题,显然是调用者的错。)在这种情况下,函数修改字符串是一种很好的设计方法。尽管您的示例是char-const,但我的问题是关于const-char,但是还是要感谢
    char-const
    const-char
    是一样的。我更喜欢