简体   繁体   English

就 function 参数传递而言,C++ 中是否有任何“可变”类型,就像在 python 中一样

[英]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. Python 使用按引用调用系统: 如果您将 arguments 之类的整数、字符串或元组(又名“可变”类型)传递给 ZC1C425268E68385D1AB5074C1,因为您不能更改调用-按-F值传递给 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. 而传递可变对象可以被视为通过引用调用,因为当它们的值在 function 内部发生更改时,它也会在 function 外部反映。 If we define "mutable" against the backdrop of this call-by-reference system, is there any "mutable" type in C++?如果我们在这个引用调用系统的背景下定义“可变”,那么 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?换句话说,当传递到按值调用 function 时,是否有任何类型的值变化将反映在 function 之外?

Also a side question: Why does python utilize the call-by-reference system?还有一个附带问题:为什么 python 使用引用调用系统? At the first glance, it seems that mutable types in python may cause concurrency problems.乍一看,似乎 python 中的可变类型可能会导致并发问题。

No and Yes, it's slightly different in C++. No 和 Yes,在 C++ 中略有不同。

In c++ mutable permits modification of the class member declared mutable even if the containing object is declared const.在 c++ 中,可变允许修改声明为可变的 class 成员,即使包含的 object 声明为 const。 In here we can change the class variable name even though we have created constant object.在这里,我们可以更改 class 变量名称,即使我们已经创建了常量 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.您在 python 中引用的那个在 C++ 中是不可能的,按值传递的变量永远不能更改从调用的 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.好吧,在 C++ 中,传递事物和变异是明确的。 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 .如果您不希望指针或 ref 发生突变,您可以通过值传递或使您的 function 参数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 和 C++ 都具有这些并发特性。

Python uses call by ref everywhere, and the non mutable types offer something close to a call by value. Python 在任何地方都使用按引用调用,非可变类型提供接近按值调用的东西。

C++ is more C++更多low level低级explicit.明确的。 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.如果您按值传递某些内容,则被调用者将始终获得原始 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.这意味着如果传递的 object 包含自身的指针引用,则引用或指针的副本仍将指向原始 object 指向的相同元素。 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.但是在这里,由于类可以包含复制构造函数或赋值运算符的自定义版本,class 设计器可以选择复制的浅或深。

TL/DR: In python the language says that variables are passed by reference. TL/DR:在 python 中,该语言说变量是通过引用传递的。 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.在 C++ 中,一切都是按值传递的,但程序员可以决定传递值(并依赖于完成复制)或传递显式引用或指针。

For the additional question, Python uses call by reference for efficiency.对于附加问题,Python 使用引用调用来提高效率。 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.复制引用只是一个地址(通常为 32 或 64 位),而按值传递需要完整的 object 的副本,该副本可能很大。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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