C++ 交换常量字符*和标准::字符串

C++ 交换常量字符*和标准::字符串,c++,stl,C++,Stl,我正在重构一个旧的C库,目前正在更改外部API,以便它使用std::string而不是const char* ColumnType Table::getColType(const char *name) const { int id = getColumnId(name) ; return getColType(id) ; } and int Table::getColumnId (const char * col_name) const { unsigned int

我正在重构一个旧的C库,目前正在更改外部API,以便它使用std::string而不是const char*

ColumnType Table::getColType(const char *name) const
{
    int id = getColumnId(name) ;
    return getColType(id) ;
}

and

int Table::getColumnId (const char * col_name) const
{
    unsigned int i = 0;

    while ((i < m_table.num_cols) && (strcmp(m_table.cols[i]->name, col_name) != 0) )
        i++;

    if (i < m_table.num_cols)
        return i;
    else
        return -1;
}
ColumnType表::getColType(const char*name)const
{
int id=getColumnId(名称);
返回getColType(id);
}
和
int Table::getColumnId(常量字符*列名称)常量
{
无符号整数i=0;
while((iname,col_name)!=0))
i++;
if(i
致:

ColumnType表::getColType(const std::string&name_in)const
{
const char*name=name_in.c_str();
int id=getColumnId(名称);
返回getColType(id);
}
及
int Table::getColumnId(const std::string和col_name_in)const
{
const char*col_name=col_name_in.c_str();
无符号整数i=0;
while((iname,col_name)!=0))
i++;
if(i
在新代码中,我将一个const char*传递给现在需要引用const std::string的函数。我知道std::string可以从const char*初始化,代码编译正确(没有警告等)

但我只是想确保我没有做任何以后会伤害我的事情(把I18n问题放在一边)

简言之-我所做的是“安全的”吗?

1)无需在getColType中从std::string获取c_str(),只需将std::string&直接传递到getColumnId中即可


2) 您应该使用重写的或直接使用而不是strcmp。请参见

它是安全的,只要执行正确,就不会造成任何伤害

尽管如此,我不认为我会建议继续这样做,除非你能指出一个实质性的好处

更安全的方法是添加一个函数,该函数接受常量
字符串&
,并直接传递到
常量char*
函数。这样,您就可以让客户机保留
std::string&
代码,而无需修改内部结构

例如:

ColumnType Table::getColType(const std::string& name_in) const
{
    return getColType(name_in.c_str());
}

小心包含空值的
std::string
s。C++类很好用;NULL并不特别。但C字符串当然会将其视为字符串的结尾。以下内容不尽相同:

if (std_string_a == std_string_b) { /* C++ way */ }

// vs.

const char *cstring_a = std_string_a.c_str(),
           *cstring_b = std_string_b.c_str();
if (0 == strcmp(a, b)) { /* C way */ }

当你混合和匹配时,你必须担心C++模式表示错误时产生的奇怪错误,但是C方式表示真。

为什么要通过<代码> const char */COD>,而不是<代码>字符串本身?我唯一能想到的是,每个调用都会有不必要的拷贝……很遗憾,C++对象不能很好地跨越图书馆的边界。或者更具体地说,如果双方使用不同的库、不同的编译器、不同的设置或一天中的不同时间进行编译,则可能会失败…@MooingDuck,当然;但从他的代码片段来看,似乎对接受
std::string
getColumnId
的调用传递了一个
const char*
-确实有点多余…@Nim:My bad,没有看到这一点。HomunculusReticulli:当您将字符串立即转换回
constchar*
并忽略它们时,为什么您的函数会接受字符串?这会强制执行不必要的副本。@Nim:是的,我意识到有额外的字符串副本正在生成,但我不想对500多个函数进行大规模重构。这是一个“第一关”(只是处理API),一旦它起作用(它是),那么我打算清理内部(比如消除不必要的字符串复制等。不过,Mooing Duck提出了一个关于不同编译器版本之间的std::string兼容性的好观点。我不是说你不应该这样做,但你应该理解当你购买这个时,它会带来什么。为什么
std::string::compare
而不是直观的
操作符=
>?@AndyT很好。我会将其添加到答案中,但保留compare方法作为备用方法。这是正确的答案。外部库应该在其接口上使用最基本/本机/简单的类型(如果从您尚未考虑的内容链接,则可以从任何语言理解的类型)。请看一下.net程序员对使用复杂类/结构作为参数的本机代码的调用。@MartyTPS我认为您提供的指导是很好的指导,但实际上问题应该决定解决方案。是否在可用性/安全性之间进行折衷,由开发人员决定ND兼容性,这应该取决于客户的需求。
if (std_string_a == std_string_b) { /* C++ way */ }

// vs.

const char *cstring_a = std_string_a.c_str(),
           *cstring_b = std_string_b.c_str();
if (0 == strcmp(a, b)) { /* C way */ }