3、和第一种方法相比,该方式也存在着同样的效率问题。

  由于该函数返回的是string对象本身,而不是对象的指针或引用,因此在函数返回时,将产生一次拷贝构造,用来生成并初始化返回的string对象。在该拷贝构造中,内存重新分配和内存数据拷贝等指令均将会被执行。然而需要指出的是,和前两种方法相比,该方法避免了对象封装性被破坏和可能造成的堆内存混乱等问题的发生,从而更好的保证了程序在运行时的稳定性。

  需要另行指出的是,在实际开发中的绝大多数情况下,调用者针对此类函数返回的字符串都仅仅是执行读操作,如数据比较、数据打印或直接插入数据库等。只有在极个别的时候才会去主动修改它,因此额外的内存分配和拷贝操作所带来的开销往往是另人沮丧的。

  在经过对上述三种方法的深入分析之后我们得出结论,为了更好和更彻底的解决字符串对象相关代码的移植问题,我们将不得不另辟蹊径,以找出运行效率较高、代码移植成本低的方式。下面将给出我在实际移植Java代码到C++代码的过程中所采用的方法,见如下代码片段:

1     String getName() {
2         return _name;  //这里_name成员变量的类型不是char*,而是String。
3     }

  怎么会和Java的代码一样呢?是的,你没有看错,是和Java的代码一样,只是这里的String被我偷梁换柱了。

  由于在移植过程中会经常遇到类似这样的代码,如果采用上述方法之一,其结果是后面的代码移植工作将会变得异常艰难。因为这些方法有的折损了C++语言本身在性能上的优势,有的则使本来不够安全的C++代码(相比于Java)变得更加不安全,简直是雪上加霜。然而这仅仅是开始,也是整个移植过程中针对字符串对象所遇到的问题中的一小部分,更多的麻烦则源于对字符串对象的操作和使用上。

  众所周知,Java中的String类型提供了大量的公有方法用于操作字符串对象,其功能无论是在丰富程度还是易用性方面均远远好于C++标准模板库中提供的string类型。在性能方面,由于JVM为String等类型的对象提供了常量池机制,因此在以上Java代码中,将不会产生任何额外的内存数据拷贝指令。

  为了解决上述诸多问题,我决定参照Java中String类型提供的常用功能,为我的C++程序重新实现一个与之对应String类型,这样不仅在性能上可以得到有效的保证,更重要的是在整个移植过程中,所有和字符串操作相关的代码移植将变得更加容易。我认为这应该是一个一劳永逸的选择了,因为今后不管是移植其他Java代码,还是直接用C++实现新的功能,该String类型都将会有更多的用武之地。见如下代码声明:

class String
 {
 public:
     String();
     String(const String& other);
     String(const char* otherText);
     String(const char otherChar);
     String(const char* otherText, const int count);
     String(const char* otherText, const int offset, const int count);
     explicit String(const int value);
     explicit String(const int64 value);
     explicit String(const double value);
     ~String();
 
 public:
     const String& operator= (const String& other);
     const String& operator= (const char* otherText);
     const String& operator= (const char otherChar);
     const String& operator+= (const String& other);
     const String& operator+= (const char* otherText);
     const String& operator+= (const char otherChar);
     const String  operator+ (const String& other) const;
     const String  operator+ (const char* otherText) const;
     const String  operator+ (const char otherChar) const;
     String& operator<< (const String& other);
     String& operator<< (const char* otherText);
     String& operator<< (const char otherChar);
     String& operator<< (const int otherDecimal);
     String& operator<< (const int64 otherDecimal);
     String& operator<< (const float otherDecimal);
     String& operator<< (const double otherDecimal);
     bool operator== (const String& other) const;
     bool operator== (const char* otherText) const;
     bool operator== (const char otherChar) const;
     bool operator!= (const String& other) const;
     bool operator!= (const char* otherText) const;
     bool operator!= (const char otherChar) const;
     bool operator> (const String& other) const;
     bool operator> (const char* otherText) const;
     bool operator> (const char otherChar) const;
     bool operator>= (const String& other) const;
     bool operator>= (const char* otherText) const;
     bool operator>= (const char otherChar) const;
     bool operator< (const String& other) const;
     bool operator< (const char* otherText) const;
     bool operator< (const char otherChar) const;
     bool operator<= (const String& other) const;
     bool operator<= (const char* otherText) const;
     bool operator<= (const char otherChar) const;
     const char operator[] (const int index) const;
     operator const char*() const;
 
 public:
     void append(const char* otherText,int count = -1);
     bool isEmpty() const;
     size_t length() const;
     size_t capacity() const;
     bool equals(const char* otherText,const size_t count,bool ignoreCase) const;
     bool equalsIgnoreCase(const String& other) const;
     bool equalsIgnoreCase(const char* otherText) const;
     bool equalsIgnoreCase(const char otherChar) const;
     int compareIgnoreCase(const String& other) const;
     int compareIgnoreCase(const char* otherText) const;
     int compareIgnoreCase(const char otherChar) const;
     bool startsWith(const char* otherText, bool ignoreCase) const;
     bool startsWith(const char otherChar, bool ignoreCase) const;
     bool endsWith(const char* otherText, bool ignoreCase) const;
     bool endsWith(const char otherChar, bool ignoreCase) const;
     String toUpperCase() const;
     String toLowerCase() const;
     const String substring(const int startPos, const int count) const;
     const String substring(const int startPos) const;
     bool contains(const char* childText, bool ignoreCase) const;
     bool contains(const char childChar, bool ignoreCase) const;
     bool containsAnyOf(const char* childText) const;
     int indexOf(const char* childText, bool ignoreCase) const;
     int indexOf(const char childChar, bool ignoreCase) const;
     int indexOf(const int startPos,const char* childText, bool ignoreCase) const;
     int indexOf(const int startPos,const char childChar, bool ignoreCase) const;
     int indexAnyOf(const char* childText, bool ignoreCase) const;
     int indexAnyOf(const int startPos, const char* childText, bool ignoreCase) const;
     int lastIndexOf(const char* childText, bool ignoreCase) const;
     int lastIndexOf(const char childChar, bool ignoreCase) const;
     int lastIndexAnyOf(const char* childText, bool ignoreCase) const;
     String trim() const;
     String ltrim() const;
     String rtrim() const;
     String insert(const int pos,const char newChar) const;
     String insert(const int pos,const char* newText) const;
     String replace(int startPos,int count,const char* newText,const int textCount);
     int toIntValue(bool* ok = 0) const;
     int64 toInt64Value(bool* ok = 0) const;
     double toDoubleValue(bool* ok = 0) const;
     bool toBoolValue() const;
     const char* text() const;
 
 private:
     const char* _buffer;
     size_t _dataLength;
 }