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

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

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


当前回答

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是通过值和值是引用传递的,所以它不需要复制构造函数。

其他回答

有几种情况需要考虑。

参数修改("out"和"in/out"参数)

void modifies(T &param);
// vs
void modifies(T *param);

这个例子主要是关于样式:你想让代码看起来像call(obj)还是call(&obj)?但是,有两点是有区别的:下面的可选情况,以及在重载操作符时希望使用引用。

...和可选的

void modifies(T *param=0);  // default value optional, too
// vs
void modifies();
void modifies(T &param);

参数未修改

void uses(T const &param);
// vs
void uses(T param);

这是一个有趣的例子。经验法则是“容易复制”的类型是通过值传递的-这些通常是小类型(但不总是)-而其他类型是通过const ref传递的。然而,如果你需要在你的函数中进行复制,你应该通过值传递。(是的,这暴露了一些实现细节。这是c++。)

...和可选的

void uses(T const *param=0);  // default value optional, too
// vs
void uses();
void uses(T const &param);  // or optional(T param)

所有情况之间的差异都很小,所以选择任何让你的生活更轻松的情况。

Const by value是一个实现细节

void f(T);
void f(T const);

这些声明实际上是完全相同的函数!当按值传递时,const纯粹是一个实现细节。试试吧:

void f(int);
void f(int const) { /* implements above function, not an overload */ }

typedef void NC(int);       // typedefing function types
typedef void C(int const);

NC *nc = &f;  // nc is a function pointer
C *c = nc;    // C and NC are identical types

下面是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();
}

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

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

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

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

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中传递值总是创建一个副本)


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

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是通过值和值是引用传递的,所以它不需要复制构造函数。