C++面试题(四)——智能指针的原理和实现

C++面试题(一)、(二)和(三)都搞定的话,恭喜你来到这里,这基本就是c++面试题的最后一波了。

     1,你知道智能指针吗?智能指针的原理。
     2,常用的智能指针。
     3,智能指针的实现。

  1答案:智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放,

     2, 最常用的智能指针: 

              1)std::auto_ptr,有很多问题。 不支持复制(拷贝构造函数)和赋值(operator =),但复制或赋值的时候不会提示出错。因为不能被复制,所以不能被放入容器中。

              2) C++11引入的unique_ptr, 也不支持复制和赋值,但比auto_ptr好,直接赋值会编译出错。实在想赋值的话,需要使用:std::move。

               例如:

                    std::unique_ptr<int> p1(new int(5));
                    std::unique_ptr<int> p2 = p1; // 编译会出错
                    std::unique_ptr<int> p3 = std::move(p1); // 转移所有权, 现在那块内存归p3所有, p1成为无效的指针.

              3) C++11或boost的shared_ptr,基于引用计数的智能指针。可随意赋值,直到内存的引用计数为0的时候这个内存会被释放。

              4)C++11或boost的weak_ptr,弱引用。 引用计数有一个问题就是互相引用形成环,这样两个指针指向的内存都无法释放。需要手动打破循环引用或使用weak_ptr。顾名思义,weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查weak_ptr是否为空指针。

     3, 智能指针的实现

      下面是一个基于引用计数的智能指针的实现,需要实现构造,析构,拷贝构造,=操作符重载,重载*-和>操作符。

template <typename T>
class SmartPointer {
public:
	//构造函数
	SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){
		if(p)
			*_reference_count = 1;
		else
			*_reference_count = 0;
	}
	//拷贝构造函数
	SmartPointer(const SmartPointer& src) {
		if(this!=&src) {
			_ptr = src._ptr;
			_reference_count = src._reference_count;
			(*_reference_count)++;
		}
	}
	//重载赋值操作符
	SmartPointer& operator=(const SmartPointer& src) {
		if(_ptr==src._ptr) {
			return *this;
		}
		releaseCount();
		_ptr = src._ptr;
		_reference_count = src._reference_count;
		(*_reference_count)++;
		return *this;
	}

	//重载操作符
	T& operator*() {
		if(ptr) {
			return *_ptr;
		}
		//throw exception
	}
	//重载操作符
	T* operator->() {
		if(ptr) {
			return _ptr;
		}
		//throw exception
	}
	//析构函数
	~SmartPointer() {
		if (--(*_reference_count) == 0) {
            delete _ptr;
            delete _reference_count;
        }
	}
private:
	T *_ptr;
        size_t *_reference_count;
        void releaseCount() {
		if(_ptr) {
			(*_reference_count)--;
    			if((*_reference_count)==0) {
    				delete _ptr;
    				delete _reference_count;
    			}
		}
    	}
};

int main()
{
    SmartPointer<char> cp1(new char('a'));
    SmartPointer<char> cp2(cp1);
    SmartPointer<char> cp3;
    cp3 = cp2;
    cp3 = cp1;
    cp3 = cp3;
    SmartPointer<char> cp4(new char('b'));
    cp3 = cp4;
}

转载自http://blog.csdn.net/worldwindjp/article/details/18843087#

时间: 2024-11-05 23:37:53

C++面试题(四)——智能指针的原理和实现的相关文章

【C/C++学院】0904-boost智能指针/boost多线程锁定/哈希库/正则表达式

boost_array_bind_fun_ref Array.cpp #include<boost/array.hpp> #include <iostream> #include <string> using namespace std; using namespace boost; void mainA () { array <int, 5> barray = { 1, 2, 3, 4, 5 }; barray[0] = 10; barray.at(4)

Google C++编程风格指南(四):智能指针和其他C++特性

1.对于智能指针,安全第一.方便第二,尽可能局部化(scoped_ptr): 2.引用形参加上const,否则使用指针形参:3.函数重载的使用要清晰.易读:4.鉴于容易误用,禁止使用缺省函数参数(值得商榷):5.禁止使用变长数组:6.合理使用友元-- Google特有的风情 Google有很多自己实现的使C++代码更加健壮的技巧.功能,以及有异于别处的C++的使用方式. 1.智能指针(Smart Pointers) 如果确实需要使用智能指针的话,scoped_ptr完全可以胜任.在非常特殊的情况

智能指针(二):shared_ptr实现原理

前面讲到auto_ptr有个很大的缺陷就是所有权的转移,就是一个对象的内存块只能被一个智能指针对象所拥有.但我们有些时候希望共用那个内存块.于是C++ 11标准中有了shared_ptr这样的智能指针,顾名思义,有个shared表明共享嘛.所以shared_ptr类型的智能指针可以做为STL容器的元素   下面我们来瞧瞧shared_ptr具体是咋实现的.相较auto_ptr有下面几个不同的地方: 1.引进了一个计数器shared_count,用来表示当前有多少个智能指针对象共享指针指向的内存块

C++中的auto_ptr智能指针的作用及使用方法详解_C 语言

智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足以涵盖auto_ptr的大部分内容.  auto_ptr是什么? auto_ptr 是C++标准库提供的类模板,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个拥有者.当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥

智能指针问题-c++ 智能对象声明与堆内存,请明白人指点,谢谢

问题描述 c++ 智能对象声明与堆内存,请明白人指点,谢谢 定义 含有计数器的智能类模板如下: template class SmartObjectPtr { private: T* p; public: SmartObjectPtr(T* p_=NULL) : p(p_) { if (p) p->AddRef(); }; SmartObjectPtr(const SmartObjectPtr &p_) : p((T*)p_) { if (p) p->AddRef(); }; ~Sma

xml-C++用智能指针循环打开XML文件时指针释放时出错

问题描述 C++用智能指针循环打开XML文件时指针释放时出错 小弟在VS2012中用C++编一个打开XML的程序中遇到了些问题.我打开XML的方法是通过打开一个索引XML文件(Index)然后获得子XML文件的路径,然后在根据这些路径用循环的方式打开子XML文件获取里面的信息.但是,我的程序不知道为什么出错,当子XML是只有一个时,程序就可以正常运行,当子XML是多个的时候,程序就提升出错,有数据中断.我设了断点查看错误原因,具体是在读完子XML,并进行完xmlfile.UnLoadXML()后

C++智能指针auto_ptr详解

auto_ptr auto_ptr是C++标准库中()为了解决资源泄漏的问题提供的一个智能指针类模板(注意:这只是一种简单的智能指针) auto_ptr的实现原理其实就是RAII,在构造的时候获取资源,在析构的时候释放资源,并进行相关指针操作的重载,使用起来就像普通的指针. std::auto_ptr<ClassA> pa(new ClassA); 1 1 但是由于其构造函数声明为explicit的,因此不能通过饮食转换来构造,只能显示调用构造函数 例如 auto_ptr<string&

c++-QT智能指针对应C++指针指针

问题描述 QT智能指针对应C++指针指针 shared_ptr p = make_shared(42);这样的智能指针在QT里面对应哪个?shared_ptr 对应QSharedPointer,make_shared对应QT里的哪个? 解决方案 没有对应的.用其他方法 http://doc.qt.io/qt-5/qsharedpointer.html 解决方案二: 可以用autoptr,C++ 14的 解决方案三: http://www.cnblogs.com/qytan36/archive/2

《深入理解Android》一3.2 智能指针

3.2 智能指针 智能指针(smart ptr)泛指一类原生指针的封装,它的行为非常类似于原生指针.通过它,C++程序可以自动化地实现资源管理(比如对象的自动析构)以及很多包裹指针的衍生操作,如内容拷贝.引用计数.autoLocker.lazy evaluation等. smart ptr使用广泛,有众多的原型及功能,几乎在所有的大型工程中都可以看到它们的身影,本章由于篇幅及目标定位所限,不能一一列举,有兴趣的读者可以参考STL.boost.android.chromium-base等开源代码.