我是c++编程的新手,但我有Java的经验。我需要关于如何在c++中传递对象到函数的指导。
我需要传递指针,引用,或非指针和非引用值吗?我记得在Java中不存在这样的问题,因为我们只传递包含对象引用的变量。
如果你能解释一下在哪里使用这些选项,那就太好了。
我是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中传递值总是创建一个副本)
还有更多,但这几个初学者的规则会让你走得很远。
其他回答
有几种情况需要考虑。
参数修改("out"和"in/out"参数)
void modifies(T ¶m);
// vs
void modifies(T *param);
这个例子主要是关于样式:你想让代码看起来像call(obj)还是call(&obj)?但是,有两点是有区别的:下面的可选情况,以及在重载操作符时希望使用引用。
...和可选的
void modifies(T *param=0); // default value optional, too
// vs
void modifies();
void modifies(T ¶m);
参数未修改
void uses(T const ¶m);
// 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 ¶m); // 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
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是通过值和值是引用传递的,所以它不需要复制构造函数。
下面是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
}
}
就像所有通过引用/指针传递一样,不是线程安全的。
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中传递值总是创建一个副本)
还有更多,但这几个初学者的规则会让你走得很远。