C ++ std :: string构造函数

时间:2008-10-09 22:58:08

标签: c++ hp-ux stdstring

对此的任何想法都将不胜感激:

std::string s1 = "hello";
std::string s2 = std::string(s1);

我现在期望这两个字符串是独立的,即我可以将“,world”附加到s2,而s1仍然会读取“hello”。这是我在Windows和Linux上找到的但是在HP_UX机器上运行代码似乎s2和s1是相同的字符串,所以修改s2会改变s1。

这听起来绝对疯狂,有人见过类似的东西吗?

5 个答案:

答案 0 :(得分:5)

虽然我无法重现OP的确切错误,但我在HP-UX aCC编译器中遇到了类似的错误。我在HP boards上发布了这个帖子,最终得到了惠普的回复。基本上他们的版本3.xx(3.70,3.73,3.67等)的aCC搞砸了std :: string构造。我们不得不转向6.xx版本的编译器。我们当时遇到的问题是PA-RISC机器没有6.xx编译器,只有安腾。我相信2007年9月为PA-RISC发布了6.xx编译器。

提出问题的代码是:

#include <iostream>
#include <string>

class S : public std::string  // An extension of std::string
{
public:
  explicit S(const char* s)
    : std::string(s)
  {
  }
};

class N     // Wraps an int
{
public:
  explicit N(int n)
    : _n(n)
  {}
  operator S() const   // Converts to a string extension
  {
    return _n == 0 ? S("zero") : (_n == 1 ? S("one") : S("other"));
  }
private:
  int _n;
};

int main(int, char**)
{
  N n0 = N(0);
  N n1 = N(1);

  std::string zero = n0;
  std::cout << "zero = " << zero << std::endl;
  std::string one = n1;
  std::cout << "zero = " << zero
            << ", one = " << one << std::endl;

  return 0;
}

这是印刷:
零=零
零=一个 ,一个=一个

换句话说,从n1构造字符串1完全破坏了另一个字符串(字符串零)。

注意:
要查看编​​译器的版本,请键入“aCC -V”
要查看机器类型,请键入“uname -m”(9000/800 ==&gt; PA-RISC,ia64 ==&gt; Itanium)

答案 1 :(得分:3)

这一定是个bug。 std :: string可以将引用计数字符串作为其实现,但是一旦它被更改,它就应该“分叉”字符串。

答案 2 :(得分:1)

这对我来说肯定听起来像个错误。有权访问HP / UX的其他人是否可以重新启用此功能?

你是说这个程序在两行显示相同的文字?

#include <stdio.h>
#include <string>

int main () 
{
    std::string s1 = "hello"; 
    std::string s2 = std::string(s1);   // note: std::string s2( s1); would reduce the number of copy ctor calls

    s2.append( ", world");

    printf( "%s\n", s1.c_str());
    printf( "%s\n", s2.c_str());
}

答案 3 :(得分:1)

这两个字符串实际上是否有不同的变化,或者您正在使用其他比较(例如c_str()返回的地址)?

某些字符串实现在复制时不会复制整个字符串,以加快复制长字符串的速度。如果您尝试对任何一个进行更改,那么实现应该复制字符串并进行适当的更改(理想情况下作为同一操作的一部分)。

答案 4 :(得分:1)

这肯定是一个缺陷。这个例子是C ++标准的逐字记录:

string s1("abc");
string::iterator i = s1.begin();
string s2 = s1;
*i = ’a’;  // Must modify only s1