2013-04-13 9 views
4

Возможно ли в C++ создать подстроку в качестве указателей в ту же память, что и исходная строка?Подстрока C++ по указателям

Допустим, у меня есть строка s = "just testing" и функция f. Я хочу, чтобы функция f возвращала константный строковый объект (пользователь не может его изменить), который будет подстрокой s, и я хочу f, чтобы создать эту подстроку наиболее эффективным способом.

Единственная идея, которую я получил, - вернуть пару указателей - в начале и в конце подстроки, но я бы хотел дать конечному пользователю «чувство», что f возвращает объект, и он может печатать он, перебирать его и т. д.

Возможно ли это на C++?

+1

См. Http://www.boost.org/doc/libs/1_53_0/libs/utility/doc/html/string_ref.html – hmjd

+0

... и ['QStringRef'] (http: // harmattan-dev. nokia.com/docs/library/html/qt4/qstringref.html) в Qt – deepmax

+0

Да, конечно, это возможно, но лучше иметь более безопасное средство, а затем просто 2 необработанных указателя. То есть вам нужен класс, который обеспечил бы эту функциональность и абстрактный клиент с точным способом его реализации. –

ответ

4

Да, это возможно.

Вы должны написать свой собственный класс в качестве обертки вокруг начала и конца подстроки.

Этот код не является полным, но показывает направление.

class string_ref 
{ 
    std::string::iterator b, e; // begin and end 
public: 
    string_ref(std::string::iterator b, std::string::iterator e) : b(b), e(e){} 

    std::string to_string() const { 
     return std::string(b, e); 
    } 

    std::string::iterator begin() const { 
     return b; 
    } 

    std::string::iterator end() const { 
     return e; 
    } 
    // ... Code to complete this class ... // 
}; 

std::ostream &operator<<(std::ostream &out, const string_ref &str) { 
    // out << str.to_string(); 
    for (std::string::iterator i = str.begin(); i != str.end(); i++) cout << *i; 
    return out; 
} 

int main() { 
    std::string s = "Hello"; 
    string_ref sr(s.begin(), next(s.begin(),3)); // pick first 3 charaters 
    cout << sr << endl;       // print it by cout 
} 

Вы можете перепрограммировать и распечатать его просто.

+0

Вы все еще делаете копию 'to_string()'. То, что автор просил, состоит в том, чтобы иметь только «доступ» только для чтения к части исходной строки. Другими словами, дополнительных распределений памяти не должно быть. Поэтому эта реализация является наивной. –

+0

@Haroogan: 'to_string()' является обязательным, если вы хотите использовать 'string_ref' рядом с другими STL. Хранение начальных и конечных итераторов - это «_view_». И у него нет дополнительного выделения памяти, вы бы мне это показали? (Этот код основан на известных подходах boost и Qt для хранения подстрок) – deepmax

+1

Я уже говорил вам, что при использовании 'to_string()' вводится дополнительное выделение памяти. Да, действительно необходимо работать со стандартным библиотечным кодом. Однако, например, реализация 'operator <<' в вашем случае делает это ненужное распределение памяти, используя 'to_string()', вместо того, чтобы напрямую передавать поток с символами. –

Смежные вопросы