C++;指向类 我现在正在读一本C++书,我对指派课堂有点困惑。

C++;指向类 我现在正在读一本C++书,我对指派课堂有点困惑。,c++,class,pointers,methods,operators,C++,Class,Pointers,Methods,Operators,本书前面的示例以这种方式使用类和方法: Calculator myCalc; myCalc.launch(); while( myCalc.run() ){ myCalc.readInput(); myCalc.writeOutput(); } Calculator* myCalc = new Calculator; myCalc -> launch(); while( myCalc -> run() ){ myCalc -> readInput(

本书前面的示例以这种方式使用类和方法:

Calculator myCalc;
myCalc.launch();

while( myCalc.run() ){
    myCalc.readInput();
    myCalc.writeOutput();
}
Calculator* myCalc = new Calculator;
myCalc -> launch();

while( myCalc -> run() ){
    myCalc -> readInput();
    myCalc -> writeOutput();
}
但是,现在改为这样做:

Calculator myCalc;
myCalc.launch();

while( myCalc.run() ){
    myCalc.readInput();
    myCalc.writeOutput();
}
Calculator* myCalc = new Calculator;
myCalc -> launch();

while( myCalc -> run() ){
    myCalc -> readInput();
    myCalc -> writeOutput();
}
我似乎找不到一个解释来解释为什么它会这样做

为什么我要以这种方式指向一个类,而不是使用标准的方式

有什么区别?在什么情况下,其中一种情况更可取


谢谢。

两者都是标准配置。一个不比另一个好

第一个是在狭窄范围内声明和使用的典型局部变量

指针方法允许您动态分配内存并将其分配给指针类型;这就是“星”符号的意思。这些变量可以从方法中传递出来,也可以分配给成员变量,在方法退出后继续存在


但是您必须意识到,当您处理完指针所指的对象时,您还负责清理内存。如果不这样做,很多人最终会用“内存泄漏”耗尽长时间运行的应用程序。

当变量是类的实例或引用时,使用点(.),而使用->如果变量是指向类实例的指针。

首先,您不是指向类,而是指向类的实例,也称为对象。(C++中的类是不可能的,如果你问我的话,它的一个缺点)。 区别在于对象的分配位置。当你在做:

Calculator myCalc;
整个对象是在上创建的。堆栈是本地变量、嵌套调用等的存储,通常限制为1MB或更低。另一方面,堆栈上的分配更快,因为不涉及内存管理器调用

当您这样做时:

Calculator *myCalc;
除了在堆栈上分配a之外,不会发生太多事情。指针的大小通常为4或8字节(32位体系结构与64位体系结构),并且只保存一个内存地址。您必须分配一个对象,并通过执行以下操作使指针指向该对象:

myCalc = new Calculator;
也可以组合成一行,如示例所示。在这里,对象分配在上,它大约与物理内存一样大(不考虑交换空间和体系结构限制),因此您可以在那里存储更多的数据。但速度较慢,因为内存管理器需要启动并在堆上为对象找到一个空闲位置,甚至需要从操作系统获取更多内存。现在指针
myCalc
包含对象的内存地址,因此它可以与
*
->
运算符一起使用

此外,您不能将指针或引用传递给堆栈上超出其作用域的对象,因为当作用域结束时(例如,在函数结束时),堆栈将被清除,因此对象变得不可用

哦,差点忘了提。堆上的对象不会自动销毁,因此必须像下面这样手动删除它们*:

delete myCalc;
总而言之:对于不离开其作用域的小型、短生命对象,可以使用基于堆栈的分配,而对于大型、长生命对象,堆通常是更好的选择



*:嗯,理想情况下,不是那样。使用智能指针,比如.< /p> 它们都是C++标准的一部分,但有一个核心区别。在第一种方式中,对象位于堆栈上(在堆栈中存储函数和局部变量,并在不再使用它们后将其删除)。当您将变量类型声明为指针时,您只在堆栈上存储一个指针,而对象本身则在堆上

当使用堆栈局部变量分配内存时,它会自动被C++所处理。当它在堆上时,您必须使用

new
获取内存,并使用
delete
释放内存

在堆栈示例中,您的代码使用“代码> >代码>调用方法,C++提供了一个快捷方式:<代码> > >代码>,这相当于<代码> * Obj.MultMe()/<代码>


请记住,当您使用
new
时,请始终使用。

如果变量
myCalc
的生命周期很长,则可以使用该变量。您可以在需要时使用
new
创建它,并在使用
delete
完成后将其删除。这样你就不必担心在不需要的时候随身携带它,而且只会占用空间。或者,您可以在需要时随意重新初始化它,等等

或者,当您有一个非常大的类时,通常的做法是使用
new
在堆而不是堆栈上分配它。这是堆栈空间不足、堆更大、所以堆空间更便宜的时代遗留下来的东西


当然,最常见的用法是分配动态数组
myCalc=新计算器[x]
;创建
x
新计算器。如果您事先不知道
x
有多大,就无法使用静态变量执行此操作;要创建多少个对象

除了符号/语法上的明显差异。将数据传递到函数时,指针通常很有用

void myFunc(Calculator *c) {
    ...
}
通常优先于

void myFunc(Calculator c) {
    ...
}
因为第二个需要一份计算器的副本。指针只包含指向的位置,因此它只引用内存中的另一个点,而不包含数据本身。另一个很好的用途是字符串,想象一下读取文本文件并调用函数来处理文本,如果字符串不是指针,则每个函数都会复制字符串。指针可以是4字节或8字节,具体取决于机器的体系结构,因此在将指针传递给函数时可以节省大量时间和内存

但在某些情况下,使用副本可能会更好。也许你只是想返回一个修改过的版本