简体   繁体   中英

In terms of function parameter passing, is there any “mutable” type in C++ as there is in python

Python utilizes a call-by-reference system: In the event that you pass arguments like whole numbers, strings or tuples(aka "mutable" types) to a function, the passing is like call-by-value because you can not change the value of the immutable objects being passed to the function. Whereas passing mutable objects can be considered as call by reference because when their values are changed inside the function, then it will also be reflected outside the function. If we define "mutable" against the backdrop of this call-by-reference system, is there any "mutable" type in C++? In other words, is there any type whose value change will be reflected outside the function when passed into a call-by-value function?

Also a side question: Why does python utilize the call-by-reference system? At the first glance, it seems that mutable types in python may cause concurrency problems.

No and Yes, it's slightly different in C++.

In c++ mutable permits modification of the class member declared mutable even if the containing object is declared const. In here we can change the class variable name even though we have created constant object.

The one you are referring in python is not possible in C++, pass by value variables can never change the variable passed from the called function.

consider this example


#include <iostream>
#include <string.h>
using namespace std;
 
class A {
    public:
    
    mutable string name;
    int val;
    A(string s, int a)
    {
        name= s;
        val = a;
    }
     
    void changename(string p) const
    {
        name=p;
    }
   
    void display() const
    {
        cout << " name is: " << name << endl;
        cout << "Age is: "
             << val << endl;
    }
};
 
int main()
{
    const A c1("Mouse",  3);
    c1.display();
    c1.changename("Internet");
    c1.display();
    std::cout<<c1.name;
}

Well, in C++ passing things around and mutating is unambiguous. If you want to pass a variable allowing its mutation, you pass it by reference/pointer or address. If you don't want your pointer or ref to be mutated you either pass by value or make your function argument const . Here is an example:

 //d is passed by reference so its value could be changed.
 void mutate(int* d) {
   *d = 0; //OK
 }
 void mutate(int& d) {
  d = 0; // OK
 }
 // pass by value i.e object is copied.
 void no_mutate(int d) {
  d = 0; //OK. but d is copied so no effect on the original variable passed.
 }
 void  no_mutate(const int * d) {
  *d = 0; // Compiler error. d is a const pointer. Can't change it's value.
 }
 void no_mutate(const int& d) {
   d = 0; // Compiler error. d is a const ref. Can't change it's value.
 }

NOTE: If you pass objects with pointer attributes, the could/couldn't be mutated depending on how you define your copy/move constructors.

Regarding concurrency, In any case, if you want to prevent race conditions, you have to use some kind of lock or mutex. Both Python and C++ have these features for concurrency.

Python uses call by ref everywhere, and the non mutable types offer something close to a call by value.

C++ is more low levelexplicit. You can pass variables by value (pass the variable), by reference (pass a reference), or by address (pass a pointer). If you pass something by value, the callee will always get a (by default shallow) copy of the original object. The means the if the passed object contains itself references of pointers, the copies of the references or pointers will still point to the same elements the original object points to. But here again as classes can contain custom versions of the copy constructor or assignment operator, the class designer can choose where the copy will be shallow or deep.

TL/DR: In python the language says that variables are passed by reference. In C++ everything is passed by value, but the programmer can decide to pass the values (and rely on copy to be done) or pass explicit references or pointers.

For the additional question, Python uses call by reference for efficiency. Copying a reference is only one address (generally 32 or 64 bits) while passing by value require a copy of the full object which can be large.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM