char*vs std::c+中的字符串+; < >我应该使用 STD::String < /C> >何时使用 char */Cuff>管理C++中的代码> char < /C> > s?
如果性能(速度)至关重要,并且由于内存管理,您愿意接受一些有风险的业务,那么您应该使用char*vs std::c+中的字符串+; < >我应该使用 STD::String < /C> >何时使用 char */Cuff>管理C++中的代码> char < /C> > s?,c++,stl,stdstring,arrays,C++,Stl,Stdstring,Arrays,如果性能(速度)至关重要,并且由于内存管理,您愿意接受一些有风险的业务,那么您应该使用char* 还有其他的场景需要考虑吗?如果你使用字符数组类似文本等,使用STD::字符串更灵活,更容易使用。如果你用它来存储数据?使用数组(首选向量)即使性能至关重要,您最好使用向量-它允许提前分配内存(reserve()方法),并将帮助您避免内存泄漏。使用vector::运算符[]会导致开销,但是如果它是char *,则总是可以提取缓冲区的地址并将其精确索引。 在下面的情况下,您应该考虑使用 char */C
char*
还有其他的场景需要考虑吗?
如果你使用字符数组类似文本等,使用STD::字符串更灵活,更容易使用。如果你用它来存储数据?使用数组(首选向量)
即使性能至关重要,您最好使用向量
-它允许提前分配内存(reserve()方法),并将帮助您避免内存泄漏。使用vector::运算符[]会导致开销,但是如果它是char *,则总是可以提取缓冲区的地址并将其精确索引。 在下面的情况下,您应该考虑使用<代码> char */COM>:
- 此数组将传入参数
- 您预先知道数组的最大大小(您知道它或您强加它)
- 您将不会在此数组上执行任何转换
<>实际上,在C++中,代码> char */COD>经常用于固定小字词,如选项、文件名等.,如果可以大到避免复制,或者通过指向实例的指针,则可以通过STD::Stand通过字符串引用,所以我看不出使用char指针的任何优点。 我使用std::string/wstring来表示实际文本的内容
char*
对于其他类型的数据很有用,您可以确保它会像应该的那样被释放。否则,std::vector就是正确的选择
这可能有例外。
<强>何时使用C++ STD::String:/P>
- 总的来说,字符串比char*更安全,通常当您使用char*进行操作时,您必须检查以确保操作正确,在string类中,所有这些都是为您完成的
- 通常在使用char*时,您必须释放分配的内存,而不必使用string,因为它在销毁时会释放其内部缓冲区
- 使用char*可以更好地控制“幕后”发生的事情,这意味着您可以根据需要调整性能
char*
而不是std::string
的一种情况是当您需要静态字符串常量时。原因是您无法控制订单模块初始化其静态变量,来自不同模块的另一个全局对象可能在初始化之前引用您的字符串
std::string
pros:
- 为您管理内存(字符串可以增长,实现将为您分配更大的缓冲区)
- 更高级的编程接口,与其他接口配合良好 STL公司
std::string
cons:
-两个不同的STL字符串实例不能共享相同的基础缓冲区。所以,如果你通过值传递,你总是会得到一个新的副本。
-有一些性能损失,但我想说,除非您的要求是特殊的,否则它可以忽略不计。AFAIK内部大多数std::string实现写时复制、引用计数语义以避免开销,即使字符串不是通过引用传递。原始字符串用法 是的,有时候你真的能做到。当使用const char*、在堆栈上分配的char数组和字符串文本时,您可以这样做:根本没有内存分配 编写这样的代码通常比使用字符串或向量需要更多的思考和关注,但通过适当的技术可以做到这一点。使用适当的技术,代码可以是安全的,但您始终需要确保在复制到char[]时,您要么对要复制的字符串的长度有一些保证,要么优雅地检查和处理过大的字符串。如果不这样做,strcpy函数家族就有了不安全的名声 模板如何帮助编写安全的字符缓冲区 至于char[]缓冲区的安全性,模板可以提供帮助,因为它们可以为您创建用于处理缓冲区大小的封装。类似这样的模板由Microsoft实施,以提供strcpy的安全替换。这里的示例是从我自己的代码中提取的,真正的代码有更多的方法,但这应该足以传达基本思想:
template <int Size>
class BString
{
char _data[Size];
public:
BString()
{
_data[0]=0;
// note: last character will always stay zero
// if not, overflow occurred
// all constructors should contain last element initialization
// so that it can be verified during destruction
_data[Size-1]=0;
}
const BString &operator = (const char *src)
{
strncpy(_data,src,Size-1);
return *this;
}
operator const char *() const {return _data;}
};
//! overloads that make conversion of C code easier
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
return dst = src;
}
模板
类BString
{
字符数据[大小];
公众:
b字符串()
{
_数据[0]=0;
//注意:最后一个字符将始终保持为零
//如果没有,则发生溢出
//所有构造函数都应该包含最后一个元素初始化
//以便在销毁过程中进行验证
_数据[Size-1]=0;
}
常量BString和运算符=(常量字符*src)
{
strncpy(_数据,src,大小1);
归还*这个;
}
运算符const char*()const{return_data;}
};
//! 使C代码转换更容易的重载
模板
内联常量BString和strcpy(BString和dst,常量字符*src)
{
返回dst=src;
}
您可以预期std::string上的大多数操作(例如find
)都会尽可能优化,因此它们的性能可能至少与纯C对应的操作一样好
还值得注意的是,std::string迭代器经常映射到底层char数组的指针。因此,你在迭代器上设计的任何算法在性能上与在char*上设计的算法基本相同
需要注意的是,例如,操作符[]
——大多数STL实现不执行边界检查,应该将其转换为对底层字符数组的相同操作。AFAIK STLPort可以选择