1

I am trying to make my own string class without using the strings library ie. #include <string>

I am allowed to use c-style strings!

I have to make the iString ctor, copy ctor, dtor, and overload the operators >>, <<, +, *

My problem so far is that when I try to compile my work, I get this error for each of my operator+ and operator* ... which is:

warning: reference to local variable s3 returned [enabled by default]

s3 was just the iString object name.

here is what I have so far:

.h file

#ifndef __ISTRING_H__
#define __ISTRING_H__

struct iString{
  char * chars;
  unsigned int length;
  unsigned int capacity;
  iString();  // ctor
  iString(const char *); // copy ctor
  iString(const iString&); // copy ctor
  ~iString(); // dtor
};

std::istream &operator>>(std::istream &in, const iString &s);
std::ostream &operator<<(std::ostream &out, const iString &s);
iString &operator+(const iString &s1, const iString &s2);
iString &operator+(const iString &s1, const char *c_str);
iString &operator*(const iString &s, const int k);
iString &operator*(const int k, const iString &s);


#endif

.cc file

#include <iostream>
#include "istring.h"
#include <cstring>

using namespace std;

iString::iString(){  // this is my ctor
  chars = new char[1];
  length = 0;
  capacity = length + 1;
  chars[0] = '\0';
}

iString::iString(const char *word){ // this is my copy ctor from a c-string
  length = strlen(word);
  capacity = length + 1;
  chars = new char[capacity];
  strcpy(chars, word);
}

iString::iString(const iString &s){ // this is my copy ctor from an iString
  length = strlen(s.length);
  capacity = length + 1;
  chars = new char[capacity];
  strcpy(chars, s.chars);
}


iString::~iString() { //dtor
  delete [] this->chars;
}

istream &operator>>(istream &in, const iString &s){  // not done, don't worry

}

ostream &operator<<(ostream &out, const iString &s){
  //out<<s.chars;
  return out<<s.chars;
}

iString &operator+(const iString &s1, const iString &s2){ 
  iString s3;

  char *new_str;// = new char[size];
  new_str = strcat(s1.chars, s2.chars);

  s3 = iString(new_str);
  return s3;
}

// tried a different approach 
iString &operator+(const iString &s1, const char *c_str){ 

  int size = s1.length + strlen(c_str) + 1;
  char *new_str = new char[size];

  strcpy(new_str, s1.chars);
  strcat(new_str, c_str); 

  iString s3(new_str);
  delete [] new_str;
  return s3;
}

iString &operator*(const iString &s, const int k){

  int size = (s.length * k) + 1;
  char *c_str = new char[size];
  for(int i = 0; i < k; i++){
    strcat(c_str, s.chars);
  }

  iString t(c_str);
  delete[] c_str;
  return t;
}

iString &operator*(const int k, const iString &s){
  return s * k;
}
4

3 に答える 3

1

問題は、返された後に s3 が破棄されているため、呼び出し元が最終的に文字列を取得すると、それは既に破棄されているため無効な文字列への参照になることです。

IE: 関数に対してローカルな文字列への参照を返しています。呼び出し元に到達すると、それはもはや存在しません。

必要なのは、値で返すことです。このようにして、文字列は返された後も有効です。C++11 では、移動の構築と代入を提供する限り右辺値参照があるため、これは効率的であることが知られています。また、C++98 では、多くの場合、これを効率的にするために戻り値の最適化を適用する多くのコンパイラを当てにすることができます。

于 2013-06-24T02:51:22.963 に答える
0

この警告は、ローカル変数であるオブジェクトへの参照を返していることを示しています。関数が戻るときにローカル変数が破棄されるため、これは問題です。

std::stringは、文字列オブジェクトへのoperator+参照ではなく、新しい文字列オブジェクトを返します。おそらく同じことを行う必要があります。別の方法は、新しいオブジェクトを作成してポインターを返すか、オペレーターに渡された文字列の 1 つを変更することですが、どちらもあまり良くないようです。

于 2013-06-24T02:51:55.183 に答える