将类对象指针传递给函数进行初始化 C++

发布于 2024-11-26 18:30:27 字数 467 浏览 4 评论 0原文

假设我有一个类“A”和这个函数:

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

我写:

A* classPointer;

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

initializationFunction(classPointer);

除非我在函数声明中通过引用传递它,否则这将不起作用:

void initializationFunction(A*& classPointer);

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

感谢您的解释:)

Lets say I have a class "A" and this function:

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

I write:

A* classPointer;

Then I pass this pointer to this function:

initializationFunction(classPointer);

This will not work unless I pass it by reference in the function declaration:

void initializationFunction(A*& classPointer);

I thought reference passing was for non-pointer type variables. I mean you don't need to pass an array by reference...

Thanks for the explanations :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

落花浅忆 2024-12-03 18:30:27

是的,确实如此。您必须通过引用传递参数(或者您可以改为传递 A**)。

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

但是,如果您无法编辑该类,那么您可以这样做:

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

A *classPointer = initializationFunction();

在我看来,这种方法比您的方法更好。

注意我没有更改函数的名称和其他变量。我想这不是这篇文章的重点。但我相信你会想要更好的真实代码名称。

Yeah, that is true. You've to pass the argument by reference (or you can pass A** instead).

But the best solution is to write the constructor of A in such way that you wouldn't need this function in the first place. That is, whatever you're doing in this function, you should be doing that in the constructor itself.

If, however, you cannot edit the class, then you can do this instead:

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

A *classPointer = initializationFunction();

In my opinion, this approach is better than yours.

Note I didn't change the name of the function and other variables. I guess that isn't the point of the post. But I believe you would want better names for real code.

烈酒灼喉 2024-12-03 18:30:27

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

void initializationFunction(A** classPointer);

要点是您正在传递一个指针参数,并且您想要修改它在调用者中拥有的值。这是一个out参数,out参数应该通过引用传递,而不是通过值传递(这里的引用意味着通过指针或引用)。此输出参数是一个指针,因此您应该传递一个指向该指针的指针或对该指针的引用。

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

void initializationFunction(A* classPointer);

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

另一种方法是从函数返回新的 classPointer :

    A* initializationFunction(void);

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

A* classPointer = initializationFunction();

Either you declaration with the reference or the following one will do:

void initializationFunction(A** classPointer);

The point is that you are passing in a pointer argument and that you want to modify the value it had in the caller. This is an out parameter and out parameters should be passed by reference, not by value (reference here means either through a pointer or reference). This out parameter is a pointer, so you should pass a pointer to that pointer or a reference to that pointer.

In other words, you need to access the original argument in the caller stack to be able modify it. In the declaration

void initializationFunction(A* classPointer);

classPointer is akin to a local variable defined inside of initializationFunction and is just a copy of the classPointer you allocated in the caller function. Modifying a copy of classPointer will not modify the original variable, so you need a pointer to the original variable to be able to modify it. The same holds true if you use a reference to the original classPointer.

An alternative approach you have is returning the new classPointer from your function:

    A* initializationFunction(void);

in this case the caller would simply do:

A* classPointer = initializationFunction();
锦欢 2024-12-03 18:30:27

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

You can pass any variable by reference. The difference between passing by reference and passing by value, is that when you pass by reference, you are in fact passing the very same pointer that is pointing to the value in that memory location, and when you pass by value you are just passing another reference to that memory location, and therefore anything you assign to it will NOT change the value of the parameter passed.

夏の忆 2024-12-03 18:30:27

像您一样使用双指针 (a**) 或引用。

Either use a double pointer (a**) or a reference as you did.

倾城°AllureLove 2024-12-03 18:30:27

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

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

In your first example, the pointer is passed by value (ie. the function gets a copy of the pointer). The object that the pointer points to is of course the same both in the calling code and inside the function.

In the second example, the pointer is passed by reference (ie. the function basically uses the same pointer as the calling code).

浪漫之都 2024-12-03 18:30:27

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

您可以复制该快捷方式并将其粘贴到窗口中的任何位置,双击它,它会在“我的文档”中打开文本文件。即通过引用/指针传递。快捷方式指向“哪里”,然后你用它来改变“东西”。

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

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

say you had a windows shortcut pointing to a text file in "My Documents".

you can copy that shortcut and paste it anywhere in windows, double click on it, and it opens the text file in "My Documents". That is passing by reference / pointer. The shortcut points to "where", then you use it to change the "stuff".

However, the code you posted doesn't "open" the file pointed to by the shortcut. It actually changes the shortcut to point to (actually create ) a new "file". But since the shortcut itself was first copied ( passed by value ), the effect is that you allocated memory but cannot access it. So analogously you changed the shortcut, created a "file", but then deleted the directory with that shortcut in there ( but your file is then lost in outer space !).

Unfortunately, there is really no analogy for passing a shortcut itself by reference, you would basically have to copy the shortcut back out of the directory, then replace the original text file in "my documents" with a shortcut to this new "file". Hope this helps instead of confuses it further :(.

德意的啸 2024-12-03 18:30:27

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

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

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

The reason you have to pass the pointer by reference is that you're actually changing where in memory it points to. If you had already assigned it to an object and wanted to modify that object, passing it directly to the function would be fine.

When you do a Aptr = new A(...), you are
- Creating an 'A' object somewhere on the heap
- Assigning the address of the newly created object to Aptr

If the function doesn't have a reference to Aptr, the function can't change its value.

海拔太高太耀眼 2024-12-03 18:30:27

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

You can pass pointers by reference because pointers are also variables with their own address.
For example, in a 32-bit architecture, you can declare an unsigned int and use it as a pointer.

吾性傲以野 2024-12-03 18:30:27

这是正常的。

我解释一下:

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

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

所以:

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

在这里你明确地说 toto 参数是 X*& (X* 代表类型,&(引用)让其值在函数 foo 内修改)

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

使用这样的实现,X** 也可以达到目的:

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

This is normal.

I explain:

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

toto value will be poped out from call stack with it's initial value (as any other argument , pointer or not)
since it's not possible to change function argument value UNLESS it's a reference.

so:

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

Here you explicitely say toto argument as being X*& (X* for type , and & (reference) to let it's value be modified inside function foo)

Pointer types are the same than any other types. replace X* by int and you'll immediately find that toto won't be changed outside of function call unless passed as reference.

An X** would also have done the trick , using such implementation:

void foo(X** toto)
{
 *toto=new X();
}
弃爱 2024-12-03 18:30:27

它应该是:

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

调用:

initializationFunction(&ptr);

该函数将设置传入 new A(......); 的参数

示例: http://ideone.com/u7z6W

It should be:

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

Call:

initializationFunction(&ptr);

the function will set the argument passed in to the new A(......);

example: http://ideone.com/u7z6W

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文