7
回答
c++这两种字符串的处理方式哪个更好一些?
华为云实践训练营,热门技术免费实践!>>>   

下面这两种字符串的处理方式哪个更好一些呢?

1:

string genGMArg(string VMPath, string mountPoint, string partition)
{
	char buf[1024];
	sprintf(buf, " -a %s -m %s --rw %s", VMPath.c_str(), mountPoint.c_str(), partition.c_str());
	return string(buf);
}
2:
string genGMArg(string VMPath, string mountPoint, string partition)
{
	return string(“-a”)+VMPath+string("-m")+partition+string("--rw")+mountPoint;
}

好久没用c++了,对于c++的类的构造以及临时变量的产生模糊了,哪位大牛能分析一下?

举报
yandong
发帖于5年前 7回/527阅
共有7个答案 最后回答: 5年前

如果你真的这么在乎临时变量的话,可以这么写:

string genGMArg(const string &VMPath,
                const string &mountPoint,
                const string &partition)
{               
        string ret;
        ret.reserve(1024);
        std::stringstream sst(ret);
        sst << "-a" << VMPath << "-m" << partition << "--rw" << mountPoint;
        return ret;
}

首先把传入参数变成引用,这样可以避免copy;另外,只要不算太老的编译器都会支持NRV优化,return ret不会产生多余的copy。

如果你用的是一个C++11编译器,甚至还可以这样写:

string &&genGMArg(const string &VMPath,
                  const string &mountPoint,
                  const string &partition)
{               
        string ret;
        ret.reserve(1024);
        std::stringstream sst(ret);
        sst << "-a" << VMPath << "-m" << partition << "--rw" << mountPoint;
        return std::move(ret);
}

这样一次copy都不会有,ret自带的buffer会直接交给接收返回值的变量

--- 共有 1 条评论 ---
yandong你好牛逼啊,你是做什么工作的啊 5年前 回复

就这两个函数而言,总体效率第一种好点:

第一种:包括buf、string(buf)、以及return产生的临时变量总共3次内存分配2次string类型构造。

第二种:包括3次string、一次临时变量总共4次内存分配4次string类型构造。

第一种长度不安全,建议使用snprintf;参数都是值传递,每次传递都会产生3个临时变量,建议用引用。

个人看法,不对希望指正

--- 共有 3 条评论 ---
adler回复 @yandong : sprintf不产生临时变量,第一种里边是return的时候会产生临时变量,是string(buf)的副本 5年前 回复
yandongsprintf接受的不也是指针么(char *),传给它的是string.c_str(),为什么还会产生临时变量? 5年前 回复
yandong很透彻,谢了 5年前 回复
第一种存在截断可能。

第2种要修改:
      string temp; temp.capacity(1024);
      temp+="-a”;temp+=VMPath;temp+="-m";temp+=partition;temp+="--rw";temp+=mountPoint;
   return temp;
可以参考 (more) effetive c++,

--- 共有 6 条评论 ---
billzhengstring temp; temp.capacity(1024); 你指的是 temp.reserve(1024); 吧? 5年前 回复
Lunar_Lin回复 @billzheng : “好看的代码都是要付出代价的。” 个人的观点。除了天生的直观语法外,试图制造好看的写法,要么导致语法隐喻不一致,要么导致性能低下。就像算法中的时空一样。 5年前 回复
Lunar_Lin回复 @billzheng : 我是针对楼主的写法 提的effective C++, 具体章节不清楚了,C++里不要写连加这样的表达式。定义temp,实际上没比其他写法 多更多的内存和内存拷贝。快捷点的话,用stringstream的方法更合适。 5年前 回复
billzheng回复 @Lunar_Lin : 无法同意 5年前 回复
Lunar_Lin回复 @billzheng : 不管是C++还是C表达式都是会产生临时对象的。对于C++更是要注意表达式写法。你写习惯就觉得好看了。好看的代码都是要付出代价的,js和lisp都很好看。 5年前 回复

如果你的参数只是std::string 那么第二个函数可以了。第一种因为sprintf是类型不安全的函数,建议不使用,即使要用也是snprintf。

如果你的参数还支持其他类型那么可以有第三者选择。

你的2个函数入参应该改为引用,这样避免了函数被调用的时候的拷贝.

  std::string genGMArg(const std::string& VMPath, 
					 const std::string& mountPoint, 
					 const std::string& partition)
{
	std::stringstream ss;
	ss << "-a" << VMPath << "-m" << partition << "--rw" << mountPoint;
	return ss.str();
}
--- 共有 1 条评论 ---
yandong嗯嗯,对哦,还有stringstream可以用 5年前 回复
顶部