Expert C++
上QQ阅读APP看书,第一时间看更新

Behavior

In previous examples, we assigned 5 and then 4 to the rating member variable. We can easily make things unexpectedly wrong by assigning invalid values to the object, like so:

cpp_book.rating = -12;

-12 is invalid in terms of the rating of a product and will confuse users, if allowed to. We can control the behavior of the changes made to the object by providing setter functions:

void set_rating(Product* p, int r) {
if (r >= 1 && r <= 5) {
p->rating = r;
}
// otherwise ignore
}
...
set_rating(&cpp_book, -12); // won't change the state

An object acts and reacts to the requests from other objects. The requests are performed via function calls, which otherwise are called messages: an object passes a message to another. In the preceding example, the object that passed the corresponding set_rating message to the cpp_book object represents the object that we call the set_rating() function in. In this case, we suppose that we call the function from main(), which doesn't actually represent any object at all. We could say it's the global object, the one that operates the main() function, though there is not an entity like that in C++.

We distinguish the objects conceptually rather than physically. That's the main point of thinking in objects. The physical implementation of some concepts of object-oriented programming is not standardized, so we can name the Product struct as a class and claim that cpp_book is an instance of the Product ,and that it has a member function called set_rating(). The C++ implementation almost does the same: it provides syntactically convenient structures (classes, visibility modifiers, inheritance, and so on) and translates them into simple structs with global functions such as set_rating() in the preceding example. Now, let's dive into the details of the C++ object model.