好吧,所以我最近深入研究了C ++并且让一切都失败了。指针最终开始变得有意义,直到我应该使用它们,如何正确实现它们等等。
然而,关于指针的基本用法还有一个小问题,我仍然需要回答。我会直接跳到代码:
使用以下课程A
和函数foo(A* bar)
...
class A
{}
void foo(A* bar)
{}
...以下对foo
的调用之间的区别是什么?
A* a;
A b;
foo(a);
foo(&b);
他们都编译得很好,据我所知,我没有遇到任何问题。
我认为A b;
在那里被实例化,而A* a;
需要用new
创建(因为它实际上没有创建对象,它只是保持一个4字节长引用潜在的A
对象。)
我可以,如果我正确地考虑这一点,请a = b;
(编辑制作a = &b
)然后成功将a
传递给{{1 }}。但是,如果我没有foo
和a = &b
尝试读取foo
指向的(不存在的)对象,则会导致运行时错误。
另外,如果以上是正确的,那么我认为我可以成功地呼叫a
。
我说错了吗?
谢谢!
答案 0 :(得分:5)
是的,您的理解是正确的。
foo(&b);
将已存在的A
类型对象的地址作为参数传递给函数foo()
。
foo(a);
将指针传递给类型A
作为函数参数。为了能够做任何有意义的事情,它必须指向一个有效的A
对象。它可以通过两种方式完成:
在堆栈上分配对象:
在堆栈(本地存储)上创建类型A
的对象&使指针a
指向此对象:
A* a;
A b;
a = &b;
动态内存分配:
A *a = new A;
但是,一旦你进行动态内存分配,你将不得不记得在使用后明确释放alloated内存,否则你将有内存泄漏:
delete a;
请注意,尽可能避免动态分配总是更好,如果必须这样做,请使用 Smart pointers 而不是原始指针。
答案 1 :(得分:4)
你不能a = b
。
必须为a = &b
,才能将a
设置为 b
的地址。
内存管理也是正确的:b
在堆栈上分配,而a
仅为指针分配空间,并为您创建实际对象。
foo(&b)
将处理文件,其中foo(a)
的行为在初始化*a
之前未定义(例如通过a = new A()
)。
答案 2 :(得分:3)
在C ++中,指针是第一类对象。指针不仅仅是一个不可见的引用,需要关联的对象具有标识。这就是Java / C#引用的工作方式(或其他大多数语言),但指针本身就是一个对象。
所以A* a
声明一个指针。它没有指向任何东西,并且没有指向任何东西。如果/当它指向某个东西时,它不需要拥有那个东西。
所以你不需要做a = new A()
。您也可以执行a = &b
(让a
包含对象b
的地址。或者它也可以指向A
类型的任何其他对象。只是一个存储地址的对象。这是你理解的关键,你要抛弃它“有一个”需要被创建的对象“的概念。
是一个对象,它包含一个地址(或者它包含特殊值null),如果它包含一个地址,则可能有也可能没有{{1}类型的对象在那个地址。
答案 3 :(得分:0)
你大多是正确的。您不应该假设指针是4个字节(例如,在amd64系统上它可能是8个)。此外,您的作业应为a = &b;
(请注意添加地址运算符)。除此之外,这听起来很合理。