在我们平时写代码或阅读代码时,经常会看到,某个类A中需要使用另一个类B的方法。那么下面会看到两种用法:
- 一种是直接定义一个B类对象。
- 一种是在类A中定义一个B类指针;
如:
// 头文件
std::shared_ptr<cv::Mat> img_ptr_;
std::shared_ptr<BlockingQueue<std::shared_ptr<cv::Mat>>>
img_queue_ptr_;
// .cc文件
// std::make_shared在动态内存中分配一个对象并初始化它, 返回指向此对象的shared_ptr
img_ptr_= std::make_shared<cv::Mat>;
img_queue_ptr_ = std::make_shared<BlockingQueue<std::shared_ptr<cv::Mat>>>(1);
//定义在 头文件 .h 中,声明一个基类接口指针,没分配内存
std::unique_ptr<Visualizer> visualizer_;
//在 .cc文件中,将指针重置为类指针,并分配内存
visualizer_.reset(new Visualizer());
还有下面这种基类子类指针用法:
//定义在 头文件 .h 中,声明一个基类接口指针,没分配内存
std::unique_ptr<BaseDetector> detector_;
//在 .cc文件中,将指针重置为某个具体子类指针,并分配内存
detector_.reset(new Pix2pixDetector());
原文链接
类的指针:他是一个内存地址值,他指向内存中存放的类对象(包括一些成员变量所赋的值).
对象,他是利用类的构造函数在内存中分配一块内存(包括一些成员变量所赋的值).
在应用时:
1.引用成员: 对象用" . “操作符; 指针用” -> "操作符.
2.生命期: 若是成员变量,则是类的析构函数来释放空间;若是函数中的临时变量,则作用域是该函数体内.而指针,则需利用delete 在相应的地方释放分配的内存块.
注意:用new ,一定要delete…
类的对象:用的是内存栈,是个局部的临时变量.
类的指针:用的是内存堆,是个永久变量,除非你释放它.
当类是有虚函数的基类,Func是它的一个虚函数,则调用Func时:
类的对象:调用的是它自己的Func;
类的指针:调用的是分配给它空间时那种类的Func;
对于一个类的对象和这个类的指针(用new运算符分配内存)在应用时有何区别
1.类和对象是两回事,对象是类的实例;
2.对象是在栈中分配的,使用new生成的对象是在堆中分配的;
3.要发挥虚函数的强大作用,必须使用指针来访问对象.
指针可以实现多态,直接用对象不行
执行定义对象,在栈空间
new的在堆
类型决定了你能做什么.
其实作用基本一样 都是为了调用类的成员变量 和成员函数用的
当你希望明确
使用这个类的时候,最好使用对象,如果你希望使用C++中的动态绑定,则最好使用指针或者引用
指针和引用用起来更灵活,容易实现多态
等
1.在类的声明尚未完成的情况下,可以声明指向该类的指针,但是不可声明该类的对象…
2.父类的指针可以指向子类的对象…
定义对象实例时,分配了内存。指针变量则未分配类对象所需内存,除非new
了
指针变量是间接访问,但可实现多态(通过父类指针可调用子类对象),并且没有调用构造函数。
直接声明可直接访问,但不能实现多态,声明即调用了构造函数(已分配了内存)。
至于那个效率高要看程序调用过程而定。
C++的精髓之一就是多态性,只有指针或者引用可以达到多态。对象不行
用指针:
第一实现多态。
第二,在函数调用,传指针参数。不管你的对象或结构参数多么庞大,你用指针,传过去的就是4个字节。如果用对象,参数传递占用的资源就太大了
原文链接
C++编程过程中,在一个类的数据成员是一个类时,定义这个成员变量为对象还是指针是有讲究的。
在C++中,
ClassTest objTest;
就已经构造了对象,分配了空间
而在C#
、Java
中,
ClassTest objTest;
只是声明,并没有分配空间。
在C++中,ClassTest objTest;
是在栈上分配空间,ClassTest *pobjTest = new ClassTest;
是在堆上分配空间。
栈分配的空间自动回收,堆分配的空间需要手动回收。
那么对于C++
类中数据成员为类类型时,将它定义为对象还是指针,并没有绝对的情况,具体情况可以具体对待。
本质上是对象分配区域的问题:前者是在栈(stack)上分配空间,后者是在堆(heap)上分配空间。
一般来说,可以定义为对象,在如下情况考虑把数据成员定义成指针:
- 1)有多态的情况;会用到虚函数,基类指针;
- 2)可能和别的类共享,或只是引用别的类里的某个对象,所以生命周期不是很确定(这个可以考虑智能指针);
- 3)大数据类,如果定义成对象,会导致当前对象无法在栈内创建。