我是c++编程的新手,但我有Java的经验。我需要关于如何在c++中传递对象到函数的指导。

我需要传递指针,引用,或非指针和非引用值吗?我记得在Java中不存在这样的问题,因为我们只传递包含对象引用的变量。

如果你能解释一下在哪里使用这些选项,那就太好了。


当前回答

c++ 11的经验法则:

通过值传递,除非

你不需要对象的所有权,一个简单的别名就可以了,在这种情况下,你传递const引用, 你必须改变对象,在这种情况下,使用一个非const左值引用, 将派生类的对象作为基类传递,在这种情况下需要通过引用传递。(使用前面的规则来确定是否通过const引用传递。)

实际上不建议传递指针。可选参数最好表示为std:: Optional(对于旧的std库boost:: Optional),并且通过引用可以很好地实现混叠。

c++ 11的move语义使得按值传递和返回更有吸引力,即使是对复杂的对象。


c++ 03的经验法则:

通过const引用传递参数,除非

they are to be changed inside the function and such changes should be reflected outside, in which case you pass by non-const reference the function should be callable without any argument, in which case you pass by pointer, so that users can pass NULL/0/nullptr instead; apply the previous rule to determine whether you should pass by a pointer to a const argument they are of built-in types, which can be passed by copy they are to be changed inside the function and such changes should not be reflected outside, in which case you can pass by copy (an alternative would be to pass according to the previous rules and make a copy inside of the function)

(这里,“传递值”被称为“传递复制”,因为在c++ 03中传递值总是创建一个副本)


还有更多,但这几个初学者的规则会让你走得很远。

其他回答

将对象作为参数传递给函数有三种方法:

通过引用传递 按值传递 在参数中添加常数

看下面的例子:

class Sample
{
public:
    int *ptr;
    int mVar;

    Sample(int i)
    {
        mVar = 4;
        ptr = new int(i);
    }

    ~Sample()
    {
        delete ptr;
    }

    void PrintVal()
    {
        cout << "The value of the pointer is " << *ptr << endl
             << "The value of the variable is " << mVar;
   }
};

void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}


int main()
{

  Sample s1= 10;
  SomeFunc(s1);
  s1.PrintVal();
  char ch;
  cin >> ch;
}

输出:

说我在someFunc 指针的值为-17891602 变量的值是4

下面是c++中传递参数/形参给函数的方法。

1. 的价值。

// passing parameters by value . . .

void foo(int x) 
{
    x = 6;  
}

2. 通过引用传递。

// passing parameters by reference . . .

void foo(const int &x) // x is a const reference
{
    x = 6;  
}

// passing parameters by const reference . . .

void foo(const int &x) // x is a const reference
{
    x = 6;  // compile error: a const reference cannot have its value changed!
}

3.通过对象。

class abc
{
    display()
    {
        cout<<"Class abc";
    }
}


// pass object by value
void show(abc S)
{
    cout<<S.display();
}

// pass object by reference
void show(abc& S)
{
    cout<<S.display();
}

按值传递:

void func (vector v)

当函数需要与环境完全隔离时,按值传递变量,即防止函数修改原始变量,以及防止其他线程在函数执行时修改其值。

缺点是复制对象要花费CPU周期和额外的内存。

通过const引用传递:

void func (const vector& v);

此表单模拟值传递行为,同时消除复制开销。该函数获得对原始对象的读访问权,但不能修改其值。

缺点是线程安全:其他线程对原始对象所做的任何更改都将在函数仍在执行时显示出来。

通过非const引用传递:

void func (vector& v)

当函数必须回写一些值给变量时,使用此方法,这些值最终将被调用者使用。

就像const引用情况一样,这不是线程安全的。

通过const指针传递:

void func (const vector* vp);

与通过const-reference传递的功能相同,只是语法不同,加上调用函数可以传递NULL指针,以表明它没有要传递的有效数据。

不是线程安全的。

传递非const指针:

void func (vector* vp);

类似于非const引用。当函数不应该回写值时,调用者通常将变量设置为NULL。在许多glibc api中都可以看到这个约定。例子:

void func (string* str, /* ... */) {
    if (str != NULL) {
        *str = some_value; // assign to *str only if it's non-null
    }
}

就像所有通过引用/指针传递一样,不是线程安全的。

我需要传递指针,引用,或非指针和非引用值吗?

这是一个在编写函数和选择参数类型时很重要的问题。这个选择将影响函数的调用方式,这取决于一些事情。

最简单的选择是按值传递对象。这基本上是在函数中创建对象的副本,这有很多优点。但有时复制的代价很高,在这种情况下,常量引用const&s通常是最好的。有时你需要你的对象被函数改变。然后需要一个非常量引用&。

有关参数类型选择的指导,请参阅c++核心指南的函数部分,从F.15开始。作为一般规则,尽量避免使用原始指针,*。

Since no one mentioned I am adding on it, When you pass a object to a function in c++ the default copy constructor of the object is called if you dont have one which creates a clone of the object and then pass it to the method, so when you change the object values that will reflect on the copy of the object instead of the original object, that is the problem in c++, So if you make all the class attributes to be pointers, then the copy constructors will copy the addresses of the pointer attributes , so when the method invocations on the object which manipulates the values stored in pointer attributes addresses, the changes also reflect in the original object which is passed as a parameter, so this can behave same a Java but dont forget that all your class attributes must be pointers, also you should change the values of pointers, will be much clear with code explanation.

Class CPlusPlusJavaFunctionality {
    public:
       CPlusPlusJavaFunctionality(){
         attribute = new int;
         *attribute = value;
       }

       void setValue(int value){
           *attribute = value;
       }

       void getValue(){
          return *attribute;
       }

       ~ CPlusPlusJavaFuncitonality(){
          delete(attribute);
       }

    private:
       int *attribute;
}

void changeObjectAttribute(CPlusPlusJavaFunctionality obj, int value){
   int* prt = obj.attribute;
   *ptr = value;
}

int main(){

   CPlusPlusJavaFunctionality obj;

   obj.setValue(10);

   cout<< obj.getValue();  //output: 10

   changeObjectAttribute(obj, 15);

   cout<< obj.getValue();  //output: 15
}

但这不是一个好主意,因为你最终会编写大量涉及指针的代码,指针很容易发生内存泄漏,并且不要忘记调用析构函数。为了避免这种情况,c++有复制构造函数,当包含指针的对象被传递给函数参数时,你将创建新的内存,这将停止操作其他对象的数据,Java是通过值和值是引用传递的,所以它不需要复制构造函数。