c++中构造对象实例的两种方式及其返回值
c++中,构造对象实例有两种方式,一种返回对象实例,一种返回该对象实例的指针。如下所示:
一、两种返回值
RedisConn conn1; //得到实例conn1;RedisConn *conn2 = new RedisConn();//得到指针conn2;RedisConn conn3 = new RedisConn();//错误,类型不匹配
意思是说,RedisConn conn;就是构造了一个实例,而通过new方式的话,就是返回指针。太奇怪了,跟c#、java完全不一样啊。在c#或java中,RedisConn conn意味着conn没有赋值,new RedisConn()返回一个诚实可靠的实例。
二、后续两种不同的处理方式
1、构造于栈
RedisConn conn;
这种方式下,conn 是在栈(stack)上分配的。栈是由编译器自动管理的内存区域,用于存储局部变量。conn 的生命周期与它的作用域相关联。当程序执行离开定义 conn 的代码块时(比如函数结束),conn 会被自动销毁,其析构函数会自动调用。
这种方式的话,如果想访问它的成员函数和成员变量,通过"."号,比如conn.rec_cnt;
void function() {RedisConn conn; // 在栈上创建一个 RedisConn 实例conn.someMethod(); // 直接调用方法
} // 当函数结束时,conn 自动被销毁
优点:
自动管理内存,无需手动释放。
简单易用,适合于局部使用的小型对象。
缺点:
栈上的空间有限,不适合创建大型对象或需要长时间存在的对象。
对象的生命周期受限于其作用域。
2、构造于堆
RedisConn* conn = new RedisConn();
内存分配:new RedisConn() 在堆(heap)上为 RedisConn 对象分配内存,并返回指向该对象的指针。
生命周期:堆上的对象不会随着作用域的结束而自动销毁。你需要显式地调用 delete 来释放这块内存,否则会导致内存泄漏。
访问方式:通过 -> 操作符来访问指针所指向的对象的成员函数和成员变量。
void function() {RedisConn* conn = new RedisConn(); // 在堆上创建一个 RedisConn 实例conn->someMethod(); // 使用 -> 操作符调用方法// 记得释放内存delete conn;conn = nullptr; // 设置为 nullptr 避免悬挂指针
}
优点:
可以动态控制对象的生命周期,适合于需要长时间存在或大小不确定的对象。
堆上的空间相对较大,适合创建大型对象。
缺点:
需要手动管理内存,增加了出错的可能性(如忘记释放内存导致内存泄漏)。
分配和释放堆上的内存通常比栈上的操作更慢。
三、堆和栈
1、栈(Stack)
后进先出。
2、堆(Heap)
特殊的完全二叉树结构,存进去,自然而然得到一个位置,比如它的子节点都比它小,形成一个小山包(小土堆);或者反过来,它所有儿子都比它大。所以堆查找最大值最为快速。有最大堆,最小堆。没有好大堆。
二叉树的概念我已经忘得一干二净,依稀记得有一种二叉树是:
左边的子节点都比它小,右边的子节点都比它大
这种跟堆没有啥关系,这叫二叉搜索树,排过序的,便于搜索。
与堆相对应,可能是坨,完全没有顺序可言。