C++ 在函数外部声明对象,将其作为引用传递,然后在函数内部创建它

C++ 在函数外部声明对象,将其作为引用传递,然后在函数内部创建它,c++,C++,首先,我将尝试解释我想做什么,然后解释我正在实验的行为 我有一个main.cpp文件和一些对象,例如x、y、z。我想在main.cpp中定义这些对象,并将它们传递给函数进行初始化,最后使用它们 这是我代码的一部分 int main(){ X* x = NULL; Y* y = NULL; Z* z = NULL; function(x,y,z); x->getX(); return 0; } void function (X* x,

首先,我将尝试解释我想做什么,然后解释我正在实验的行为

我有一个main.cpp文件和一些对象,例如x、y、z。我想在main.cpp中定义这些对象,并将它们传递给函数进行初始化,最后使用它们

这是我代码的一部分

int main(){
    X* x = NULL;
    Y* y = NULL;
    Z* z = NULL;

    function(x,y,z);

    x->getX();

    return 0;
}

void function (X* x, Y* y, Z* z){
    x = new X();
    y = new Y();
    z = new Z();
}
此代码导致
x->getX()中出现分段错误。我使用gdb运行程序,并且在
function()
中正确创建了对象,但是当执行从
函数退出时,对象被销毁,并且x=y=z=0x0

我认为,当通过引用将对象传递给函数时,可以修改对象的成员,但不能修改对象本身

所以,我的问题是如何在main中声明一个对象,然后将其传递给函数进行初始化,最后在main中使用它


谢谢。

您的函数应该声明为

void function (X* &x, Y* &y, Z* &z)
因为您希望将参数作为引用传递,以便能够修改指针x、y和z

X*
表示指向X的指针

是指

所以

X*&X
表示指向X的指针的引用

查看以下问题以了解更多详细信息,其中包含您需要了解的基本知识:


您的函数应声明为

void function (X* &x, Y* &y, Z* &z)
因为您希望将参数作为引用传递,以便能够修改指针x、y和z

X*
表示指向X的指针

是指

所以

X*&X
表示指向X的指针的引用

查看以下问题以了解更多详细信息,其中包含您需要了解的基本知识:


我认为你应该使用真正好的属性,作为参考。但是,如果要使用间接传递引用,则被调用方中的实际参数应在
&
前面加上
函数(&x、&y、&z)。但是它对C++来说不好。因为它有真正的参考传递能力。我错了吗?

我认为你应该使用真正好的属性,作为参考。但是,如果要使用间接传递引用,则被调用方中的实际参数应在
&
前面加上
函数(&x、&y、&z)。但是它对C++来说不好。因为它有真正的参考传递能力。我错了吗?

您需要确认当前正在传递的值将创建您的值的副本。下面是一个简单的例子,考虑2个函数:

void dontEdit(int a) {
   a = 2;
}

void edit(int &a) {
   a = 2;
}
dontEdit
a
将被复制,更改
a
的值将不会对外部世界产生影响。在
edit
中,您为函数提供了一个对保存
a
的内存的引用,这样您就能够在函数范围之外检测到这种变化。考虑它们在这里的用途:

int main() {
    int a = 5;
    cout << "a is: " << a << endl;
    dontEdit(a); // this is pass by value, a copy of a is made.
    cout << "a is: " << a << endl;
    edit(a); // this is pass by reference, a is edited directly. 
    cout << "a is: " << a << endl;
    return 0;
}

在你的问题中,你也有同样的问题。您想要编辑
main
scope
x
,但您通过值传递它。您将创建指针
x
的副本,并将其分配给
new x()
。然后,当您返回时,
x
的副本不再存在,并且您创建的内存被挂起,您无法找到它。因此,您需要做的是通过引用传递:

最后要注意的是,
c++
没有自动垃圾收集功能,因此对于每一个
新的
都应该有一个
删除
,否则您将面临垃圾收集的风险

您需要确认当前正在传递的值将创建您的值的副本。下面是一个简单的例子,考虑2个函数:

void dontEdit(int a) {
   a = 2;
}

void edit(int &a) {
   a = 2;
}
dontEdit
a
将被复制,更改
a
的值将不会对外部世界产生影响。在
edit
中,您为函数提供了一个对保存
a
的内存的引用,这样您就能够在函数范围之外检测到这种变化。考虑它们在这里的用途:

int main() {
    int a = 5;
    cout << "a is: " << a << endl;
    dontEdit(a); // this is pass by value, a copy of a is made.
    cout << "a is: " << a << endl;
    edit(a); // this is pass by reference, a is edited directly. 
    cout << "a is: " << a << endl;
    return 0;
}

在你的问题中,你也有同样的问题。您想要编辑
main
scope
x
,但您通过值传递它。您将创建指针
x
的副本,并将其分配给
new x()
。然后,当您返回时,
x
的副本不再存在,并且您创建的内存被挂起,您无法找到它。因此,您需要做的是通过引用传递:


最后要注意的是,
c++
没有自动垃圾收集功能,因此对于每一个
新的
都应该有一个
删除
,否则您将面临垃圾收集的风险

您正在通过值进行传递,这将创建类型的副本。您不想修改指针本身,只想更改它指向的内容。因此,通过引用传递指针(而不是像代码那样通过值传递指针)是一个完美的解决方案。它创建指向对象的指针,并将指针设置为NULL。您正在通过值进行传递,这将创建类型的副本。您不想修改指针本身,只想更改它指向的内容。因此,通过引用传递指针(而不是像代码那样通过值传递指针)是一个完美的解决方案。它创建指向对象的指针,并将指针设置为NULL。我的问题是,我认为对象默认作为引用传递。你的帖子关于这个主题非常完整,谢谢,我知道你在帖子中解释的所有内容。我的问题是,我认为对象默认作为引用传递。你的帖子非常完整,谢谢