Hello! My comrades turned to me through a lichku, saying that they did not want to comment on what they did not understand or did not fully understand and asked for clarification. Based on the questions I sent, I will try to give answers in an accessible form.
In C ++ there is physical and logical constancy. Physical means that the object does not change (except for brute force). Logical means that the object is outwardly unchanged, but can change the internal state.
For example,
class Test { public: void foo() const { // m_object } private: mutable Object m_object; }; const Test test(...); test.foo();
The object has changed. Where it can be found:
There are situations when we do not need such surprises. Create an initially immutable object:
Immutable<Test> test(...);
use
test.foo();
or there is no operator yet.:
test().foo();
The test object remains unchanged. Where it is needed:
1) in parallel programming;
2) when working with the "thing in itself" and we do not want surprises.
I'll start with an example:
There is a constant object
Type x(...); f(x);
and function
void f(const Test &a) { ... const_cast<Test&>(a) = value; ... }
This may be a violation, there may be an error, but the compiler does not even peep .
Consider another situation. There is an immutable object:
Immutable<Type> x(...); f(x);
and
void f(const Immutable<Test> &a) { const_cast<Immutable<Test> &>(a) = value; }
The compiler will swear.
You can break only with the help of reinterpret_cast, which can be broken off if the protected object is stored in a non-standard way (for example, in compressed / encrypted / serialized form).
The same effect with
void f(Immutable<Test> &a) { const_cast<Immutable<Test> &>(a) = value; }
Applying Immutable, says that the object should not change.
I will not talk about FP, agent-oriented programming, about the model of actors and the blackboard, but I will say about parallel programming (the model of actors and the blackboard are actively used there).
And I will say first in an informal, somewhat exaggerated way.
Suppose there is a project on git (or on another version control system). There are N programmers. Everyone must make their version of the project. What is being done:
The result, the initial project is whole, the boss can choose from the fork-s.
Transferring this to parallel programming:
Immunity says that there are no surprises when working with them.
This is a question of taste, but it seems that the expression of the form
Immutable<Type **> p(...);
looks clearer than
const Type *const *const p = …;
because Immunity immediately says that the object should not change in any way, that constancy is used for both the address and the content .
This is also a matter of taste. But the implementation is made in accordance with the principles of the OP, while leaving room for effective work in the C ++ style. See "Overhead". You can use both the universal class Immutable and the auxiliary classes immutable :: array, immutable :: pointer, etc. These auxiliary classes are not related to each other.
You can make an object immutable initially and pass it by reference. Copies can do if necessary. No one forces you to use what you do not use.
If you want to work with internal data, you can get a copy of the internal data ONCE and work with them. For this there is a function value.
Here you can argue that by gaining access to internal data, you can spoil immobility. First, value returns constant data, and secondly, it is the programmer’s conscious actions. Many library classes return a native representation of objects, playing with which you can spoil.
But this, once again, the programmer receives internal data, and in this case constant, and this is the CONSCIOUS actions of the programmer.
For further study, I recommend:
Matthew Wilson "A Practical Approach to Solving C ++ Programming Problems":
the author of the book proposes an implementation of what he lacks in C ++ (up to C ++ 11, but some of the issues are still relevant), for example, property, etc.
Andrei Alexandrescu “Programming language D” , he has a peculiar style, but it is interesting to read how contract programming is built into PL.
Source: https://habr.com/ru/post/322450/
All Articles