2016-04-01 74 views
0

我正在學習操作符重疊。我創建了簡單的類來測試它。重載操作符和修改字符串

class Beer{ 
public: 
    Beer(int oner , int twor , string name){ 
    this -> one = oner; 
    this -> two = twor; 
    this -> name = name; 
    }; 
    int getOne(){ 

     return this -> one; 
    }; 
    int getTwo(){ 

     return this -> two; 
    }; 
    string getName(){ 
     return this -> name; 
    }; 
    Beer operator + (const Beer &a)const { 

     return Beer(5,two+a.two,"firstName"); 

    }; 
    Beer operator + (string a)const { 

     this -> name = this -> name +" "+a; 

    }; 

private: 

    int one; 
    int two; 
    string name; 
}; 

我想弄清楚,如何midify與重載操作數的字符串。我聲明的功能

​​

引發有關傳遞const字符串的錯誤。

我嘗試使用

Beer operator + (const string *a)const { 
     swap(this -> name , this -> name + " " + a); 
     return *this; 
    }; 

哪抱怨之一是cosnst字符串,塞康一個是基本的字符串。

這個想法很簡單。

Beer one (5, 6, "one") 
one + "two" 

// one.name = "one two" 

什麼是正確的方法如何做到這一點?

//與交換錯誤

error: no matching function for call to 'swap(const string&, std::basic_string<char>)'| 

//用繩子埃羅

passing 'const string {aka const std::basic_string<char>}' as 'this' argument of 'std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(std::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' discards qualifiers [-fpermissive]| 
+0

請發佈確切的編譯器錯誤,你會得到。 – aschepler

+0

順便說一句,類方法定義結束時的分號是不必要的。 – sigmalha

回答

2

評論:

  1. 不包括整個std命名空間。您可能會遇到與自己的代碼發生惡意名稱衝突。最多使用明確需要的符號,例如using std::string;

  2. 除非需要修改值的副本,否則通過const引用傳遞大小的對象,例如std::string。當您將參數聲明爲值類型std::string時,您會收到該字符串的副本,而且這很昂貴,除非需要副本在函數內部進行修改。

    這是C++標準存在的一個長期存在的問題:像這樣的實現細節應該與函數的用戶無關,會泄漏到接口(函數的聲明)中。不過,當副本有意義時,讓編譯器給你一個,而不必輸入太多。因此:

    // prefer this 
    std::string fooize(std::string foo) { 
        assert(foo.size() > 0); 
        foo.insert(1, "foo"); 
        return foo; 
    } 
    // over this 
    std::string fooize(const std::string & bar) { 
        assert(bar.size() > 0); 
        auto foo = bar; 
        foo.insert(1, "foo"); 
        return foo; 
    } 
    
  3. 使用的初始化列表,那麼你就不會需要做的愚蠢的名字體操(你有onertwor名稱:

    Beer(int one, int two, const std::string & name) : 
        one(one), 
        two(two), 
        name(name) 
    {} 
    
  4. 申報只讀訪問器常量:

    int getOne() const { return one; } 
    
  5. 通過const引用返回像string這樣的大值;用戶代碼可能會讓編譯器幫助maki在需要時自動納克副本:

    const std::string & getName() const { return name; } 
    
    // use: 
    Beer beer{0,0,""}; 
    std::cout << (beer.getName() + "!") << std::endl; // makes a copy of name as needed 
    
  6. +運營商採取的字符串,你應該返回一個新的對象,而不是修改this。你幾乎應該按照其他運營商+你所做的那樣去做。

    Beer operator +(const std::string & a) const { 
        return Beer(one, two, name + " " + a); 
    }; 
    
  7. 如果你想修改你的對象,你想operator +=

    Beer & operator+=(const std::string & a) { 
        name += " "; 
        name += a; 
        return *this; 
    } 
    
  8. 即使你的類的設計與運營商進行試驗,你應該總是考慮運營商是否使生活更輕鬆或不。例如,你班有三名成員。除非從班級的語義上明確表達,否則不清楚這些成員中的哪一個會被操作。例如,使用名爲addToOne,addToTwoappendToName的方法,而不是操作員,或者簡單地讓用戶通過設置者設置成員(如setOne(int one) { this->one = one; })會更清楚。然後用戶只需要做beer.setOne(beer.getOne() + 2);

  9. 考慮沒有get前綴的命名getter,例如,

    class Beer { 
        int m_one; 
    public int one() const { reeturn m_one; } 
    }; 
    

    它減少了用戶輸入。標準庫以及諸如boostQt之類的大型庫遵循此慣例,例如,你有std::string::size(),而不是std::string::getSize()

+0

+和+ =之間的區別是什麼?爲什麼我應該使用+ =如果我想修改當前對象? – user3706129

+1

@ user3706129因爲這是約定 – vu1p3n0x

+1

@ user3706129因爲'operator +'預計會創建一個臨時的,而'operator + ='預計會修改現有的值。這就是這些運算符在其他所有類型中的行爲,包括內置的(例如'int')和標準的(例如'std :: string')。例如。你可以寫'1 + 2',否則它會失效,因爲'+'會嘗試修改一個右值。你不能寫'1 + = 2',因爲'1'不是'+ ='所需的左值。 –

0

在你這裏operator+()

Beer operator+(string a) const 
{ 
    this->name = this->name + " " + a; 
}; 

在功能上簽名const是保證編譯器在調用函數時,不會更改中的數據對象,但您更改對象中的數據。

+0

我剛剛注意到我在那裏留下了const,但它沒有它就會拋出seg錯誤。 – user3706129

+0

不要刪除const,它是正確的,請參閱我的答案。 – Unimportant

1
Beer operator + (string a)const { 
    this -> name = this -> name +" "+a; 
}; 

你不應該改變誰的運算符+ beeing稱爲對象的內容,畢竟如果執行A = B + C,B的內容不應改變。編譯器正確地通知你這是因爲它是一個const函數。

而是創建一個臨時對象來保存'總和'並​​返回它。

Beer operator + (string a)const { 
    return Beer(one, two, name + " " + a); 
};