繁体   English   中英

将类对象指针传递给用于初始化C ++的函数

[英]Passing a class object pointer to a function for initialization C++

可以说我有一个类“ A”和此函数:

void initializationFunction(A* classPointer)
{
    ...
    ...
    classPointer = new A(.....); 
}

我写:

A* classPointer;

然后,我将此指针传递给此函数:

initializationFunction(classPointer);

除非我在函数声明中通过引用将其传递,否则这将无法工作:

void initializationFunction(A*& classPointer);

我以为引用传递是针对非指针类型变量的。 我的意思是您不需要通过引用传递数组...

感谢您的解释:)

是的,是的。 您必须通过引用传递参数(或者可以传递A**代替)。

但是最好的解决方案是编写A的构造函数,这样一来您就不需要此函数。 也就是说,无论您在此函数中执行什么操作,都应该在构造函数本身中执行此操作。

但是,如果无法编辑该类,则可以执行以下操作:

A *initializationFunction()
{
    A *obj = new A(.....); 
    //...
    return obj;
}

A *classPointer = initializationFunction();

我认为,这种方法比您的方法更好。

注意,我没有更改函数名称和其他变量。 我想这不是帖子的重点。 但是我相信您会希望使用更好的名称来表示真实代码。

您可以通过引用传递任何变量。 按引用传递和按值传递之间的区别在于,当您按引用传递时,您实际上传递的是指向该内存位置中值的指针,而当您按值传递时,您只是传递了另一个指针对该存储位置的引用,因此您分配给它的任何内容都不会更改传递的参数的值。

使用双指针(a **)或引用。

您可以通过引用进行声明,也可以通过以下声明进行声明:

void initializationFunction(A** classPointer);

关键是要传递一个指针参数,并且要修改它在调用方中具有的值。 这是一个out参数,out参数应该通过引用而不是通过值传递(这里的引用是指通过指针或引用)。 这个out参数是一个指针,因此您应该将指针传递给该指针或对该指针的引用。

换句话说,您需要访问调用者堆栈中的原始参数才能对其进行修改。 在声明中

void initializationFunction(A* classPointer);

classPointer类似于在initializationFunction函数内部定义的局部变量,并且只是您在调用程序函数中分配的classPointer的副本。 修改classPointer的副本不会修改原始变量,因此您需要一个指向原始变量的指针才能进行修改。 如果您使用对原始classPointer的引用,则同样适用。

您拥有的另一种方法是从函数中返回新的classPointer

    A* initializationFunction(void);

在这种情况下,调用方只需执行以下操作:

A* classPointer = initializationFunction();

在您的第一个示例中,指针按值传递(即,函数获取指针的副本)。 指针指向的对象在调用代码中和函数内部都相同。

在第二个示例中,该指针是通过引用传递的(即该函数基本上使用与调用代码相同的指针)。

说您有一个Windows快捷方式指向“我的文档”中的文本文件。

您可以复制该快捷方式并将其粘贴到Windows中的任何位置,双击它,然后在“我的文档”中打开文本文件。 那是通过引用/指针传递的。 快捷方式指向“ where”,然后使用它来更改“ stuff”。

但是,您发布的代码不会“打开”快捷方式指向的文件。 它实际上将快捷方式更改为指向(实际上是创建)新的“文件”。 但是由于快捷方式本身是首先复制的(通过value传递),其结果是您分配了内存但无法访问它。 因此,类似地,您更改了快捷方式,创建了一个“文件”,但是随后删除了该快捷方式所在的目录(但是您的文件随后在外层空间中丢失了!)。

不幸的是,确实没有通过引用传递快捷方式本身的类比,您基本上必须将快捷方式复制回目录之外,然后用此新“文件”的快捷方式替换“我的文档”中的原始文本文件。 希望这有助于而不是进一步混淆:(。

它应该是:

void initializationFunction(A** classPointer)
{
    ...
    ...
    *classPointer = new A(.....); 
}

呼叫:

initializationFunction(&ptr);

该函数将设置传递给new A(......);

例如: http//ideone.com/u7z6W

您必须通过引用传递指针的原因是,实际上您正在更改其指向的内存位置。 如果您已经将其分配给一个对象并想要修改该对象,则可以将其直接传递给函数。

当您执行Aptr = new A(...) ,您就是
-在堆上的某个地方创建一个“ A”对象
-将新创建的对象的地址分配给Aptr

如果该函数没有对Aptr的引用,则该函数无法更改其值。

您可以按引用传递指针,因为指针也是具有自己地址的变量。 例如,在32位体系结构中,您可以声明一个unsigned int并将其用作指针。

这很正常。

我解释:

void foo(X* toto)
{
  toto=new X();
}

toto值将使用其初始值(与其他任何参数,是否有指针一样)从调用堆栈中弹出,因为除非是引用,否则无法更改函数参数值。

所以:

void foo(X*& toto)
{
 toto=new X();
}

在这里,您明确地将toto参数说成是X *&(类型为X *,而&(引用)是在函数foo中修改它的值)

指针类型与任何其他类型相同。 用int替换X *,您将立即发现toto不会在函数调用之外更改,除非传递为引用。

使用以下实现,X **也可以解决问题:

void foo(X** toto)
{
 *toto=new X();
}

暂无
暂无

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

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