首页 文章 精选 留言 我的

精选列表

搜索[工具库],共10000篇文章
优秀的个人博客,低调大师

《C++标准程序》读书笔记(三)

STL中的智能指针auto_ptr可以实现简单的内存自动回收,防止内存泄漏(memory leakage)。auto_ptr实际是一个类,在该类析构时自动调用delete,从而达到了内存回收的效果。但是,由于同一个指针同一时刻只能被一个auto_ptr占用,如果采用赋值操作(=)或者拷贝构造函数调用,就会发生所有权转移,例如: auto_ptr<int> p(new int(0)); auto_ptr<int> q; 此时,p拥有指向一个int的指针,q的指针为空。如果执行q=p;则,p指向空,q指向int;但是,这样所有权转换的问题同样发生在参数传递中,例如 void foo(auto_ptr<int> t); 如果调用 foo(p);那么p就丢失了指针,所以一个解决方法是用引用,例如: void foo1(auto_ptr<int>& t); void foo2 (const auto_ptr<int>& t); 两者都是可以的,不过foo1非常不安全,因为在函数里面很容易通过类似赋值的操作使t丢失指针,而foo2不会。例如 void foo2(const auto_ptr<int>& t) { auto_ptr<int> m; m=t; } 会发生编译错误,从而避免灾难的发生。但随之又出现一个很大的问题,就是auto_ptr类的拷贝构造函数,或者赋值函数。最理想的情况是这样(如果能成功,就不会有别的什么问题): auto_ptr(const auto_ptr& rhs):ap(rhs.release()){} 但由于上述的原因,会发生编译错误(因为调用了release(),而release()会改变成员变量,不再是const)。所以只能去掉const,变为 auto_ptr(auto_ptr& rhs):ap(rhs.release()){} 这样可以编译成功,而且往往也能正确运行,但是唯一的问题是: 当rhs为右值时会出现问题。 为了简化问题,先假设拷贝构造函数什么都不做,即: auto_ptr(auto_ptr& rhs){} 那么,如果有 auto_ptr<int> p(new int(10)),执行 auto_ptr<int> q(p),不会有任何问题,因为p是左值。但如果执行auto_ptr<int> q(auto_ptr<int>(new int(10))) ,则会发生编译错误,因为auto_ptr<int>(new int(10)) 是右值,对右值的引用只能是常引用,也就是"const auto_ptr& rhs"的形式。但这里要注意的是,刚才那段代码用VC编译没有任何问题,并且可以顺利运行,但是用GCC之类的标准c++就不能顺利编译。 在VC中auto_ptr<int>& p=auto_ptr<int>(new int(0)) 是合法的,但在标准C++中是不合法的,只有const auto_ptr<int>& p=auto_ptr<int>(new int(0)) 才是合法的,也即在标准C++中,对右值的引用只能是常引用。所以说,要在标准C++中实现 auto_ptr<int> p(auto_ptr<int>(new int(0))) 就变得不可能了,因为如上所说,拷贝构造函数是这样的形式:auto_ptr(auto_ptr<T>& rhs):ap(rhs.release()){} 但是不能把右值传到一个非常引用中。但毕竟有聪明的人能想到解决办法,利用代理类( proxy class)声明如下结构,为了方便,我用int代替模板参 struct auto_ptr_ref { int* p; auto_ptr_ref(int *t):p(t){} }; 然后在auto_ptr类中增加了以下函数 auto_ptr(auto_ptr_ref rhs):ap(rhs.p){} auto_ptr& operator=(auto_ptr_ref rhs){reset(rhs.p); return *this;} operator auto_ptr_ref(){return auto_ptr_ref(release());} 之后,如果在标准C++有以下调用(VC中也会按照这个步骤调用,虽然没有auto_ptr_ref它也能直接调用) auto_ptr<int> p(auto_ptr<int>(new int(0))) 便可以成功,过程如下: 1. 构造临时对象 auto_ptr<int>(new int(0)) 2. 想将临时对象通过拷贝构造函数传给p,却发现没有合适的拷贝构造函数,因为只有auto_ptr(auto_ptr& rhs)这个不能用,又没有auto_ptr(const auto_ptr& rhs) (因为用了在所有权转移中会出错)! 3. 编译器只能曲线救国,看看类型转换后能不能传递。 4. 由于我们定义了 operator auto_ptr_ref() 所以编译器自然就可以试一下转为 auto_ptr_ref类型。 5. 编译器猛然间发现,我们定义了 auto_ptr(auto_ptr_ref rhs):ap(rhs.p){} 的构造函数,可以传递。 6. 顺利构造p,任务完成。 其实说白了问题很简单,因为构造函数不能接受右值,则取中间左值=右值, 然后再让函数接受中间左值。 而这一系列过程正是利用编译器能够自动进行类型转换而完成的。 本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/08/19/1271700.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

《C++标准程序》读书笔记(四)

, 复制代码 #include <iostream> #include <list> #include <algorithm> using namespace std; int main() { list<int> coll; list<int>::iterator pos25,pos35,pos; for(int i=20;i<=40;++i) coll.push_back(i); pos25 = find(coll.begin(),coll.end(),25); pos35 = find(coll.begin(),pos25,35); if(pos35!=pos25) {//pos35在pos25前 pos = find(coll.begin(),pos25,30); } else {//pos25在pos35前 pos = find(pos25,coll.end(),30); } cout<<"num: "<<*pos<<endl; system("pause"); return 0; } 复制代码 使用仿函数 复制代码 #include <functional> /* class for the compose_f_gx_hx adapter*/ template <class OP1, class OP2, class OP3> class compose_f_gx_hx_t : public std::unary_function<typename OP2::argument_type, typename OP1::result_type> { private: OP1 op1; // process: op1(op2(x),op3(x)) OP2 op2; OP3 op3; public: // constructor compose_f_gx_hx_t (const OP1& o1, const OP2& o2, const OP3& o3) : op1(o1), op2(o2), op3(o3) { } // function call typename OP1::result_type operator()(const typename OP2::argument_type& x) const { return op1(op2(x),op3(x)); } }; /* convenience function for the compose_f_gx_hx adapter*/ template <class OP1, class OP2, class OP3> inline compose_f_gx_hx_t<OP1,OP2,OP3> compose_f_gx_hx (const OP1& o1, const OP2& o2, const OP3& o3) { return compose_f_gx_hx_t<OP1,OP2,OP3>(o1,o2,o3); } 复制代码 复制代码 #include <iostream> #include <list> #include <algorithm> #include <functional> #include "compose21.hpp" using namespace std; int main() { list<int> coll; list<int>::iterator pos; for(int i=20;i<=40;++i) coll.push_back(i); pos = find_if(coll.begin(),coll.end(), compose_f_gx_hx(logical_or<bool>(), bind2nd(equal_to<int>(),25), bind2nd(equal_to<int>(),35))); cout<<"num: "<<*pos<<endl; system("pause"); return 0; } 复制代码 2,三种迭代器适配器: 1) Insert iterator 插入位置可以是容器的最前或最后,或是在某一特定位置上. 复制代码 #include <iostream> #include <vector> #include <list> #include <deque> #include <set> #include <algorithm> using namespace std; int main() { list<int> coll1; // insert elements from 1 to 9 into the first collection for (int i=1; i<=9; ++i) { coll1.push_back(i); } // copy the elements of coll1 into coll2 by appending them vector<int> coll2; copy (coll1.begin(), coll1.end(), // source back_inserter(coll2)); // destination // copy the elements of coll1 into coll3 by inserting them at the front // - reverses the order of the elements deque<int> coll3; copy (coll1.begin(), coll1.end(), // source front_inserter(coll3)); // destination // copy elements of coll1 into coll4 // - only inserter that works for associative collections set<int> coll4; copy (coll1.begin(), coll1.end(), // source inserter(coll4,coll4.begin())); // destination return 0; } 复制代码 back_inserter的内部调用push_back(),在容器尾端插入元素,只有在提供有push_back()成员函数的容器中才能使用,这样的容器有:vector,deque,list. front_inserter的内部调用push_front(),在容器最前端插入元素,只有在提供有push_ front()成员函数的容器中才能使用,这样的容器有deque和list;一般性的inserter,作用是将元素插入”初始化时接受之第二参数”所指的位置的前方.它内部调用insert(). 2)Stream iterator.这是用来读写流的迭代器. 复制代码 #include <iostream> #include <vector> #include <string> #include <algorithm> #include <iterator> using namespace std; int main() { vector<string> coll; copy (istream_iterator<string>(cin), // start of source istream_iterator<string>(), // end of source back_inserter(coll)); // destination sort (coll.begin(), coll.end()); unique_copy (coll.begin(), coll.end(), // source ostream_iterator<string>(cout,"\n")); // destination } 复制代码 3)Reverse iterator 复制代码 #include <iostream> #include <vector> #include <algorithm> #include <iterator> using namespace std; int main() { vector<int> coll; // insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll.push_back(i); } // print all element in reverse order copy (coll.rbegin(), coll.rend(), // source ostream_iterator<int>(cout," ")); // destination cout << endl; } 复制代码 3,移除元素 复制代码 #include <iostream> #include <list> #include <algorithm> #include <iterator> using namespace std; int main() { list<int> coll; // insert elements from 6 to 1 and 1 to 6 for (int i=1; i<=6; ++i) { coll.push_front(i); coll.push_back(i); } // print all elements of the collection copy (coll.begin(), coll.end(),ostream_iterator<int>(cout," ")); cout << endl; list<int>::iterator end = remove (coll.begin(), coll.end(),3);//新的尾节点 // print resulting elements of the collection copy (coll.begin(), end,ostream_iterator<int>(cout," ")); cout << endl; // print number of resulting elements cout << "number of removed elements: "<< distance(end,coll.end()) << endl; // remove ``removed'' elements coll.erase (end, coll.end()); // print all elements of the modified collection copy (coll.begin(), coll.end(),ostream_iterator<int>(cout," ")); cout << endl; } 复制代码 本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/08/27/1278096.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

获取数据架构信息,GetSchema(),参数表

CollectionName MetaDataCollections DataSourceInformation DataTypes Restrictions ReservedWords Users Databases Tables Columns StructuredTypeMembers Views ViewColumns ProcedureParameters Procedures ForeignKeys IndexColumns Indexes UserDefinedTypes privateDataTableGetSqlDatabaseSchema(stringstrConn,stringcollectionName,string[]strs) { SqlConnectionconnection=newSqlConnection(strConn); DataTableschema=newDataTable(); try { connection.Open(); if(!string.IsNullOrEmpty(collectionName)) { if(strs!=null&&strs.Length>0) { schema=connection.GetSchema(collectionName,strs); } else schema=connection.GetSchema(collectionName); } else schema=connection.GetSchema(); } catch { schema=null; } finally { connection.Close(); } returnschema; } 本文转自today4king博客园博客,原文链接:http://www.cnblogs.com/jinzhao/archive/2009/07/29/1534023.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android Studio2.2.3 通过JNI引用ffmpeg小结

修改步骤: 首先通过NDK14编译出libffmpeg.so ,将include目录取出 通过AS建立基于jni的工程项目,将include目录放到cpp下;创建jniLibs/armeabi目录,将libffmpeg.so放到里边 3.配置CMakeLists.txt 添加如下: #addtheffmpeglib include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/main/cpp/include) add_library(ffmpeg-libSHAREDIMPORTED) set_target_properties(ffmpeg-libPROPERTIESIMPORTED_LOCATION${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/armeabi/libffmpeg.so) target_link_libraries(native-lib ffmpeg-lib#ffmpeglib android#usetheandroidloglib ${log-lib}) 4.配置build.gradle 主要添加arguments 和 ndk的配置 externalNativeBuild{ cmake{ cppFlags"" arguments'-DANDROID_TOOLCHAIN=clang','-DANDROID_STL=gnustl_static' } ndk{ abiFilters'armeabi' } } 5.native_lib.cpp #include <jni.h> #include <string> #include <android/log.h> extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libswscale/swscale.h" #include "libavutil/imgutils.h" #include "libavutil/avutil.h" } #define LOG_TAG "MyTagFFmpeg" #define ALOGE(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) extern "C" jstring Java_letv_com_myffmpeg_MainActivityFFmpeg_stringFromJNI( JNIEnv *env, jobject /* this */) { std::string hello = "Hello ,this is the first ffmpeg test !"; ALOGE("%s",hello.c_str()); char info[10000] = { 0 }; sprintf(info, "%s\n", avcodec_configuration()); hello += info; return env->NewStringUTF(hello.c_str()); } That's all. 本文转自 曾永刚 51CTO博客,原文链接:http://blog.51cto.com/zyg0227/1947097

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册