簡體   English   中英

C ++-為我的字符串類重載運算符>>

[英]C++ - overloading operator >> for my string class

我意識到字符串類MyString。 這是代碼:

#include <iostream>
#include <cstring>

using std::cout;
using std::endl;

class MyString{
    private:
    char * content;
    int length;
    void copy(const MyString & source);
    public:
    MyString();
    MyString(const char * source);
    ~MyString();
    MyString(const MyString & source);
    void print(void);
    MyString & operator = (const MyString &source);
    friend std::ostream & operator << (std::ostream & out, const MyString&   towrite);
    friend std::istream & operator >> (std::istream & in, MyString & toread);
};

MyString::MyString(){
    content = new char[1];
    content[0] = '\0';
    length = 0;
}


MyString::MyString(const char *source){
    length = strlen(source);
    content = new char[length + 1];
    strcpy(content, source);
}

MyString::~MyString(){
    delete[] content;
}

void MyString::copy(const MyString & source){
    length = source.length;
    content = new char[length + 1];
    strcpy(content, source.content);
}

MyString::MyString(const MyString & source){
    copy(source);
}

void MyString::print(void){
    cout << "" << content << endl;
}

MyString &MyString::operator=(const MyString &source){
    copy(source);
    return *this;
}

std::ostream & operator<<(std::ostream & out,const MyString& towrite){
    out << towrite.content;
    return out;
}

std::istream & operator >> (std::istream & in, MyString & toread){
    int length;
    std::cout << "Enter length of word: " << endl;
    std::cin >> length;
    toread.length = length;
    toread.content = new char[toread.length+1];
    for (int i = 0; i < toread.length; i++){
    in >> toread.content[i] ;
    }
    toread.content[toread.length] = '\0';
    return in;
 }

我的問題與重載運算符>>有關。

對於此主程序:

int main(){
    MyString word;
    std::cout<<"Enter some word: "<<endl;
    std::cin>>word;
    std::cout<<"Your entered: "<<word<<endl;
}

這是輸出:

Enter some word:

Enter length of word:

5

stack

Your entered: stack

Process returned 0 (0x0)   execution time : 8.313 s

Press any key to continue.

它可以正確打印用戶輸入的字符串,但不會按照我想要的方式“模仿”原始字符串類。 這就是為什么。

如果使用C ++字符串類:

int main(){
    std::string word;
    std::cout<<"Enter some word: "<<endl;
    std::cin>>word;
    std::cout<<"Your entered: "<<word<<endl;
}

用戶無需輸入單詞長度 我可以在課堂上實現嗎?

EDIT1:

我這樣做是這樣的:

std::istream & operator >> (std::istream & in, MyString & toread){
    char *temp;
    temp = new char[100];
    char c;
    int i = 0;
    while(c != '\n'){
    c = getchar();
    temp[i++] = c;
    }
    temp[i] = '\0';
    int length = i-1;
    toread.length = length;
    toread.content = new char[toread.length+1];
    for(int i = 0 ; i < toread.length ; i++){
    toread.content[i] = temp[i];
    }
    delete [] temp;
    toread.content[toread.length+1]='\0';
}

它可以正常工作。 但是,我得到警告,因為我沒有返回“ in”:

|| ===構建:在fdsfsdf中調試(編譯器:GNU GCC編譯器)=== | C:\\ Users \\ hae \\ Desktop \\ fdsfsdf \\ main.cpp ||在函數'std :: istream&operator >>(std :: istream&,MyString&)':| C:\\ Users \\ hae \\ Desktop \\ fdsfsdf \\ main.cpp | 137 |警告:函數中沒有返回非空[-Wreturn-type] |的return語句 || ===構建完成:0個錯誤,1個警告(0分鍾,4秒)=== | || ===運行:在fdsfsdf中調試(編譯器:GNU GCC編譯器)=== |

這是我很久以前寫的類似課程的精簡版。 這是古董,但它可以工作,並解決班上的一些問題。

class charray {
public:
    charray();
    ~charray();

    charray(const charray&);
    charray(const char*);

    charray& operator=(const charray&);
    charray& operator=(const char*);

    void swap(charray&);

    const char* c_str() const
    { return m_elem; }

    unsigned int size() const
    { return m_size; }

private:
    void m_resize(unsigned int size);

    char* m_elem;
    unsigned int m_size;
};

// private.
void charray::m_resize(unsigned int size)
{
    char* elem = new char[size+1];

    memcpy(elem, m_elem, std::min(m_size, size));
    elem[size] = '\0';
    delete [] m_elem;

    m_elem = elem;
    m_size = size;
}

// public.
charray::charray()
    : m_elem(0), m_size(0)
{
    m_resize(0);
}

charray::~charray()
{
    delete [] m_elem;
}

charray::charray(const charray& src)
    : m_elem(0), m_size(0)
{
    unsigned int size = src.size();
    m_resize(size);
    memcpy(m_elem, src.c_str(), size);
}

charray::charray(const char* src)
    : m_elem(0), m_size(0)
{
    unsigned int size = std::strlen(src);
    m_resize(size);
    memcpy(m_elem, src, size);
}

charray& charray::operator=(const charray& rhs)
{
    charray temp(rhs);
    this->swap(temp);
    return *this;
}

charray& charray::operator=(const char* rhs)
{
    charray temp(rhs);
    this->swap(temp);
    return *this;
}

void charray::swap(charray& b)
{ 
    std::swap(m_elem, b.m_elem);
    std::swap(m_size, b.m_size);
}

這是您可能最感興趣的。請密切注意細節。 當直接處理內存時,有效的實現與崩潰的實現之間的區別通常非常微妙。

注意:操作員不是朋友。 他們不訪問私人數據。

std::ostream& operator<<(std::ostream& out, const charray& in)
{
    return out << in.c_str();
}

std::istream& operator>>(std::istream& in, charray& out)
{
    // verify no errors are set, flush tied streams, strip leading
    // whitespace.
    std::istream::sentry sentry(in);
    if (!sentry)
        return in;

    unsigned int size = 0;
    unsigned int tail = 0;
    char* temp = 0;
    int next; // @note int not char (to record EOF).

    while ((next = in.get()) != in.eof() && !std::isspace(next)) {
        // if temp buffer is exhausted, then double the buffer size.
        // (base size of 16).
        if (tail == size) {
            unsigned int newsize = std::max(2*size, 16u);
            char* newtemp = new char[newsize+1];
            memcpy(newtemp, temp, size);
            delete [] temp;
            temp = newtemp;
            size = newsize;
        }
        temp[tail++] = next;
    }
    // @note because the stream is prepeared with istream::sentry, there
    // will be at least one non-whitespace character in the stream.
    assert(temp != 0);
    temp[tail] = '\0';
    out = temp;
    delete [] temp;
    return in;
}

一種更簡單,更安全的方法來進行完全相同的操作,

#include <vector>
std::istream& operator>>(std::istream& in, charray& out)
{
    std::istream::sentry sentry(in);
    if (!sentry)
        return in;

    std::vector<char> temp;
    int next;

    while ((next = in.get()) != in.eof() && !std::isspace(next))
        temp.push_back(next);
    temp.push_back('\0');
    out = &temp[0];
    return in;
}

編輯
以上內容已過時(C ++ 11之前的版本)。 現代的實現可能會以不同的方式處理構造和分配。 這是這些方法的更新版本,

注意:方法m_resize消失了。 一切都通過構造函數來處理。

charray::charray(const char* src, unsigned int size)
    : m_elem{ new char[size+1]{} }, m_size{ size }
{
    std::copy(src, src + size, m_elem);
}

charray::charray()
    : charray(nullptr, 0)
{}

charray::charray(const charray& src)
    : charray(src.m_elem, src.m_size)
{}

charray::charray(const char* src)
    : charray(src, std::strlen(src))
{}

charray::charray(charray&& src)
    : m_elem{ src.m_elem }, m_size{ src.m_size }
{
    src.m_elem = nullptr;
    src.m_size = 0;
}

// handle both move and copy assignment.
charray& charray::operator=(charray rhs)
{
    this->swap(rhs);
    return *this;
}

希望這可以幫助。 祝好運。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM