我应该按值传递字符串还是将指针传递给它?

时间:2022-09-10 23:22:59

I have a function which looks like this

我有一个看起来像这样的功能

int myclass::setVersion(std::string ver)
{
  if (ver.size()>1)
  {
    version.swap(ver)
    return 0;
  }
  else 
    return -1;
}

My question is very simple, is it better to pass ver the way it is or better to pass it as a pointer to string? FYI, ver is a small size string (around 8). EDIT: it does not matter if ver is changed. I just want to replace version with the contents of ver. EDIT2: I am using visual studio 2008.

我的问题很简单,是否更好地传递它的方式或更好地传递它作为指向字符串的指针?仅供参考,ver是一个小尺寸的字符串(大约8)。编辑:如果更改ver无关紧要。我只想用ver的内容替换版本。 EDIT2:我正在使用visual studio 2008。

5 个解决方案

#1


5  

It depends on what you want the behavior of the code to be.

这取决于你想要的代码行为。

Most of the suggested answers here change the behavior from your posted code in that they will modify the string that's passed in (or make the code fail to compile because it can't modify the passed in argument).

这里建议的大多数答案都会改变发布代码的行为,因为它们会修改传入的字符串(或者使代码无法编译,因为它无法修改传入的参数)。

In the example you posted,the string passed to myclass::setVersion() will not be modified (the parameter may be modified, but that is just a copy fo the string passed in; a copy which will be destroyed when the function returns).

在您发布的示例中,传递给myclass :: setVersion()的字符串将不会被修改(参数可能会被修改,但这只是传入的字符串的副本;当函数返回时将被销毁的副本) 。

For a a case like this, I'd suggest passing a const std::string&:

对于像这样的情况,我建议传递一个const std :: string&:

int myclass::setVersion(std::string const& ver)
{
  if (ver.size()>1)
  {
    version = ver;
    return 0;
  }
  else 
    return -1;
}

This way the copy is made only when necessary.

这样,只在必要时才进行复制。

But honestly, unless the function is called often, it's probably nothing to worry much about.

但老实说,除非经常调用这个函数,否则可能没什么值得担心的。

#2


5  

In C++11 you can add an overload which accepts rvalue reference:

在C ++ 11中,您可以添加一个接受rvalue引用的重载:

int myclass::setVersion(std::string& ver);
int myclass::setVersion(std::string&& ver);

This way you'll be able to swap from rvalues as well as lvalues. And actually instead of swap you can perform a move assignment:

这样你就可以从rvalues和lvalues交换。实际上,您可以执行移动分配而不是交换:

version = std::move(ver);

This is potentially faster than swap, depending on std::string implementation.

这可能比swap更快,具体取决于std :: string实现。

Examples of usage:

用法示例:

string getVersion() { return "version2"; }

string v1 = "version1";
a.setVersion(v1);           // lvalue
a.setVersion(getVersion()); // rvalue
a.setVersion("version3");   // rvalue as well

Demo

UPDATE: Indeed, you have to have both variants of setVersion for maximum flexibility. But I agree with others in that all this is premature optimization and should be used only if profiling shows a bottleneck at this point.

更新:实际上,您必须拥有setVersion的两种变体才能获得最大的灵活性。但我同意其他人的观点,认为所有这些都是过早优化,只有在此时分析显示出瓶颈时才应使用。

#3


3  

Please pass a reference.

请传递参考。

int myclass::setVersion(std::string& ver)

#4


2  

You should pass it in by reference whenever you are modifying the string and wanting the caller to see that change.

每当修改字符串并希望调用者看到该更改时,您应该通过引用传入它。

#5


2  

You want to store the contents of ver into version. A copy has to be made, the question is where.

您想将ver的内容存储到版本中。必须制作副本,问题在哪里。

You can do it the way you propose, as swapping is fast. But I notice not all control paths cause the version string to be assigned a new value.

您可以按照建议的方式进行,因为交换速度很快。但我注意到并非所有控制路径都会为版本字符串分配新值。

Therefore I suggest the following

因此我建议如下

int myclass::setVersion(const std::string& ver)
{
  if (ver.size()>1)
  {
    version = ver;
    return 0;
  }
  else 
    return -1;
}

This will avoid a copy should the size of ver be 1, in which case you don't want to copy the string into version.

如果ver的大小为1,这将避免副本,在这种情况下,您不希望将字符串复制到版本中。

#1


5  

It depends on what you want the behavior of the code to be.

这取决于你想要的代码行为。

Most of the suggested answers here change the behavior from your posted code in that they will modify the string that's passed in (or make the code fail to compile because it can't modify the passed in argument).

这里建议的大多数答案都会改变发布代码的行为,因为它们会修改传入的字符串(或者使代码无法编译,因为它无法修改传入的参数)。

In the example you posted,the string passed to myclass::setVersion() will not be modified (the parameter may be modified, but that is just a copy fo the string passed in; a copy which will be destroyed when the function returns).

在您发布的示例中,传递给myclass :: setVersion()的字符串将不会被修改(参数可能会被修改,但这只是传入的字符串的副本;当函数返回时将被销毁的副本) 。

For a a case like this, I'd suggest passing a const std::string&:

对于像这样的情况,我建议传递一个const std :: string&:

int myclass::setVersion(std::string const& ver)
{
  if (ver.size()>1)
  {
    version = ver;
    return 0;
  }
  else 
    return -1;
}

This way the copy is made only when necessary.

这样,只在必要时才进行复制。

But honestly, unless the function is called often, it's probably nothing to worry much about.

但老实说,除非经常调用这个函数,否则可能没什么值得担心的。

#2


5  

In C++11 you can add an overload which accepts rvalue reference:

在C ++ 11中,您可以添加一个接受rvalue引用的重载:

int myclass::setVersion(std::string& ver);
int myclass::setVersion(std::string&& ver);

This way you'll be able to swap from rvalues as well as lvalues. And actually instead of swap you can perform a move assignment:

这样你就可以从rvalues和lvalues交换。实际上,您可以执行移动分配而不是交换:

version = std::move(ver);

This is potentially faster than swap, depending on std::string implementation.

这可能比swap更快,具体取决于std :: string实现。

Examples of usage:

用法示例:

string getVersion() { return "version2"; }

string v1 = "version1";
a.setVersion(v1);           // lvalue
a.setVersion(getVersion()); // rvalue
a.setVersion("version3");   // rvalue as well

Demo

UPDATE: Indeed, you have to have both variants of setVersion for maximum flexibility. But I agree with others in that all this is premature optimization and should be used only if profiling shows a bottleneck at this point.

更新:实际上,您必须拥有setVersion的两种变体才能获得最大的灵活性。但我同意其他人的观点,认为所有这些都是过早优化,只有在此时分析显示出瓶颈时才应使用。

#3


3  

Please pass a reference.

请传递参考。

int myclass::setVersion(std::string& ver)

#4


2  

You should pass it in by reference whenever you are modifying the string and wanting the caller to see that change.

每当修改字符串并希望调用者看到该更改时,您应该通过引用传入它。

#5


2  

You want to store the contents of ver into version. A copy has to be made, the question is where.

您想将ver的内容存储到版本中。必须制作副本,问题在哪里。

You can do it the way you propose, as swapping is fast. But I notice not all control paths cause the version string to be assigned a new value.

您可以按照建议的方式进行,因为交换速度很快。但我注意到并非所有控制路径都会为版本字符串分配新值。

Therefore I suggest the following

因此我建议如下

int myclass::setVersion(const std::string& ver)
{
  if (ver.size()>1)
  {
    version = ver;
    return 0;
  }
  else 
    return -1;
}

This will avoid a copy should the size of ver be 1, in which case you don't want to copy the string into version.

如果ver的大小为1,这将避免副本,在这种情况下,您不希望将字符串复制到版本中。