繁体   English   中英

如何将const char *存储到char *?

[英]How to store a const char* to a char*?

我有这个代码按预期工作:

#define MAX_PARAM_NAME_LEN 32

const char* GetName()
{
    return "Test text";
}

int main()
{
    char name[MAX_PARAM_NAME_LEN];
    strcpy(name, GetName());    

    cout << "result: " << name << endl;
}

如果我想将结果存储到char * (因为我正在使用的框架中的某些函数仅使用char *作为输入)而不使用strcpy (为了代码的实用性和可读性,以及学习),怎么可能我做? 保持const ,这很好用:

const char* name;
name = GetName();

但我仍然有const

试图只使用char*

char* name;
name = GetName();

invalid conversion from 'const char*' to 'char*' 这种转换的最佳习惯是什么?

这种转换的最佳习惯是在整个代码中使用std::string 由于您使用的框架将const char*作为其输入,因此您始终可以在std::string上传递c_str()调用的结果:

std::string GetName() {
    return "Test text";
}

int main() {
    std::string name = GetName();
    int res = external_framework_function(name.c_str());
    cout << "result: " << res << " for " << name << endl;
}

遥远的第二好是在你的代码中使用const char*

const char* name = GetName();

由于您使用的框架采用const char*您也很好。

如果需要非const指针,则无法复制字符串。 您可以为您创建一个功能,但您仍然有责任释放您从中获得的副本:

char* copy(const char* orig) {
    char *res = new char[strlen(orig)+1];
    strcpy(res, orig);
    return res;
}
...
char *name = copy(GetName());
...
delete[] name;

return "Test text"; 返回指向只读字符串文字的指针。

如果您正在使用一个以char*作为输入的const char* ,并且您有一个const char* (例如只读字符串文字),那么您应该提供从该const char*开始的字符串的深层副本const char*这些功能。

否则,如果函数尝试修改只读字符串,则会在运行时冒未定义的行为。

你现在拥有的是足够的; 假设您无法使用std::string (如果您可以使用std::string 并且所有框架函数都使用const char*输入,那么我建议您重构代码以使用std::string ,并传递c_str()方法的输出那个字符串类到你的框架函数。)

最后,如果你的一些框架函数需要一个char*那么你总是可以自己构建一个小的适配器类:

class Adapter
{
public:
    Adapter(const& Adapter) = delete; /*don't try to copy me please*/
    Adapter& operator=(const Adapter& ) = delete; /*don't try to copy me please*/
    Adapter(const char* s) : m_s(::strdup(s))
    {
    }
    ~Adapter() /*free memory on destruction*/
    {
        ::free(m_s); /*use free to release strdup memory*/
    }
    operator char*() /*implicit cast to char* */
    {
        return m_s;
    }
private:
    char* m_s;
};

然后对于函数void foo(char* c) ,可以调用foo(Adapter("Hello"/*or any const char* */)); foo可以随意嵌入匿名临时的char* 您甚至可以增强此类以将构造函数转换为char* ,在这种情况下,只会获取指针的浅表副本(并且析构函数不会删除内存)。

在C ++中,“删除const ”的典型方法是使用const_cast<>

char *name = const_cast<char*>(GetName());

当然,这是不受欢迎的,丑陋的和潜在的危险,因为GetName()确实可以返回指向不应该更改的内容的指针,然后你去允许自己更改它。 在这种情况下,这是一个很难找到错误的好方法。

解决方法是使用std::string作为临时保留区域; 这将意味着复制字符串,但这可能是性能可接受的:

std::string s(GetName());
char *name = s.c_str();

这当然只有在s超出范围时不保留name时才有效。 如果是这种情况,那么您将拥有某种形式的持久性字符串存储层。

你可以明确地施展它。 (char*) getName() 但你可能不应该这样做。 因为const位意味着“承诺不改变它”。 所以如果我有一个函数void foo(const char* string)我正在说:“给我一个指向字符串的指针。我不会改变它。” 如果你声明一个变量const char* string = "hello"; 你是说,不应该改变这个字符串。 因为你做出了这个承诺,编译器知道,并且可以使你的代码更有效率。 这就是为什么:

const char* a = "hello";
const char* b = "hello";
(a==b); //is probably true

你的编译器知道你不会改变ab所以它使它们指向同一个地址,所以它只需要存储一个"hello"字符串。 如果你现在要改变ab也会改变,这不是你想要的。

长话短说,如果你绝对确定你的调用函数没有改变字符串,你可以明确地转换它。 (或者更好的是,将函数更改为(const char*)如果它是你的)。
如果你不确定,你将不得不复制。 (就像你已经在使用strcpy() )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM