2015-08-14 2 views
17

Я новичок в C++. Книга, которую я прочитал, говорит мне, что если оператор плюс (+) был перегружен для некоторого объекта класса, скажем, класса string, чтобы сделать эту проблему более конкретной.Оператор +, разница между типами классов и встроенными типами?

#include<iostream> 
#include<string> 
using namespace std; 

int main() 
{ 
    string s1("abc"); 
    string s2("def"); 

    string s3("def"); 

    cout<<(s1+s2=s3)<<endl; 

    int x=1; 
    int y=2 
    int z=3; 
    cout<<(x+y=z)<<endl; 

    return 0; 
} 

Как вы можете ожидать, первое cout утверждение верно в то время как второй является неправильным. Жалобы компилятора x+y не является изменяемым значением lvalue. Мой вопрос: почему оператор + возвращает изменяемое значение lvalue для объектов string, но не для int?

+2

В C++ объекты являются экземплярами любого типа, включая встроенные типы. И типы - это типы. Таким образом, «объекты» и «встроенные типы» не имеют смысла. – juanchopanza

+1

@juanchopanza Было бы полезно указать правильную формулировку, пока вы на ней :) – Quentin

+1

@Quentin Я думаю, что «разница между встроенными типами и определенными пользователем типами» будет точной. – juanchopanza

ответ

20

Он не возвращает изменяемое значение lvalue для строки. Он возвращает временный объект, а s1+s2 и x+y - оба значения.

Однако объекты типа класса могут быть перегружены operator=, что string делает. Вам разрешено вызывать функции-члены для r-значений.

Разница между этими двумя случаями находится в = (не +)

+1

Обратите внимание, что это проблема, которая выполняется [http://stackoverflow.com/a/21052529/15416]. Вы можете запретить вызов 'operator =' на rvaliues ваших собственных классов. Проблема в том, что существует существующий код, который сломался бы, если бы стандарт C++ был изменен, чтобы запретить присвоение 'std :: string' rvalues. – MSalters

+0

@MSalters Да, [мудрый человек] (http://stackoverflow.com/questions/28598468/does-it-improve-safety-to-mark-assignment-operators-as-lvalue-only) однажды запросил то же самое. . :) –

14

Для std::string, s1 + s2 = s3, на самом деле:

(operator+(s1, s2)).operator =(s3) 

s1 + s2 возвращает RValue

методы члены могут быть применены к временно.
Поскольку C++ 11, мы имеем именующий/RValue классификатор для метода,
, так что вы можете запретить o1 + o2 = o3 для пользовательского типа с:

struct Object 
{ 
    Object& operator =(const Object& rhs) & ; // Note the & here 
}; 

так Object::operator = может быть применены только к Lvalue.