C++中假如创建类A的对象a。
可以这样做:
(1): A a;
(2): A *p=new A;
这两种方法的异同:
A a; 这样的对象的内存分配在栈上,超出作用域(比如在函数fun中创建的a对象,在函数结束后,就超出了作用域) 就调用析构函数将对象销毁。
A *p=new A;这种的内存是分配在堆上的,分配之后到程序结束前一直存在,除非你用delete p;这样才会调用析构函数将对象消亡.
示例:
#include <iostream.h>
class tree{
int height;
public:
tree(int Height){
height=Height;
}
~tree(){cout<<"****";}
friend ostream& operator <<(ostream &os,const tree*t){
return os<<"tree height is:"<<t->height<<endl;
}
};
int main(){
tree *T= new tree(40);
cout<<T;
//delete T;
//tree t(40);
//cout<<&t;
return 0;
}
运行结果:
tree height is:40
Press any key to continue
如果取消对delete T; 语句的注释,运行结果为:
tree height is:40
****Press any key to continue
如果mian()为:
int main(){
//tree *T= new tree(40);
//cout<<T;
//delete T;
tree t(40);
cout<<&t;
return 0;
}
运行结果为:
tree height is:40
****Press any key to continue
以下引用相关辨析:
A a; 这种写法完全是C语言的遗留问题,还要为值和引用分别写拷贝构造函数,有些繁琐了,java和.net就没这种情况了,所有的对象都是引用类型,而且运用原形模式实现ICloneable接口可以代替拷贝构造函数,其实完全可以用指针或者引用来处理问题.
java和.net因为内存垃圾回收机制才敢这么做,C++在局部函数结束后直接把局部对象全给释放了,效率高。
而java即使GC也是"建议"进行垃圾收集,收集速度也不敢恭维。
C++和java 创建对象的异同(转):
创建对象:C++和Java的异同
C++ | Java |
类定义: Class User {...}; | 类定义: Class User {...} |
对象构造: (1) User u(...); 对象构造: (2) User * p = new User(...);
| 对象构造: User q = new User(...); |
在标号为(1)的构造函数调用中,我们可以把u本身当作一个User对象。这个构造函数调用填充由u对象所占据的内存区域,如下图(a)部分所示。
标号为(2)的构造函数调用创建了一小块内存区域,其中存储了p的值(一个内存地址),然后填充一个较大的内存区域,赋值符右边所创建的User对象就存储在这块内存中。p所指向的内存地址就是User对象存储位置。如下图(b)部分所示
Java的构造函数调用也保留一个内存位置存储q的值,并填充一块内存保存User对象。在这种情况下,为q的值所保留的内存地址保存了User对象引用,如下图(C)部分所示。
我们可以把q中存储的对象引用看成是一个伪指针(一个内存伪地址),之所以说它是伪指针,是因为我们不能像C++指针那样对它进行解引用。如果由于内存管理的需要,JVM决定把这个User对象移动到内存中的一个不同位置,q所保存的对象引用仍然能够找到这个对象。反之,如果p所指向的对象转移到内存中的不同位置,那么p的值需要在程序的控制下进行显示的修改。