读书人

【转载BYR】一年来遇到的C++有关问题和

发布时间: 2012-12-28 10:29:05 作者: rapoo

【转载BYR】一年来遇到的C++问题和解决方法,分享一下

转载自BYR?bupteinstein

原帖链接:http://bbs.byr.cn/article/CPP/47554

?

?

----------------------------------------------------------------2010.01.02问题描述:当自己写一个类的时候,如何确定成员变量和成员函数的访问权限?解决方法:根据《Effective C++》所说,所有成员变量都应声明为private,这样可以保证该类的public用户(类使用者)和protected用户(派生类撰写者)都可以不因你要修改类而修改他们的代码。----------------------------------------------------------------2010.01.02问题描述:当自己写一个类的时候,有些功能只依赖于类的public接口函数。当需要用函数封装该功能时,是写成成员函数、友元函数还是普通函数?解决方法:根据《Effective C++》所说,当然是普通函数。这样增强了类的封装性,实现新功能也更灵活。相关功能的普通函数还可以声明到一个namespace中作进一步打包封装。用namespace可以在很多文件中实现向同一个namespace添加功能函数,扩展灵活,编译依存度更低,使用起来语意像类的静态成员函数一样清晰。有百利而无一害。----------------------------------------------------------------2010.01.02问题描述:为什么将自定义代码放在std命名空间里会出错?问题原因:因为std的所有成员,都能且只能由C++标准委员会指定。解决方法:1.没招儿,没法解决。2.将代码写在别的命名空间内,用的时候using对应的namespace。3.最根本的办法,你去成为C++标准委员会的一员,提交提案并说服其他委员在定C++标准的时候,把你这段代码加到std命名空间去。----------------------------------------------------------------2010.01.08问题描述:在类继承体系中,为什么会出现“鸟都会飞——企鹅是鸟——但企鹅不会飞”这样的悖论?问题原因:因为软件世界和现实世界有一些不同。在软件世界中,类的继承表示派生类能拥有基类的所有行为,而且严格拥有。但在现实世界中,我们说“鸟都会飞”,是说“一般的鸟都会飞”,并不是很严格的继承关系。解决方法:1.严格地使用抽象继承体系,对世界做贴近软件规则的抽象;2.根据软件的应用范围,灵活设计继承体系;(换句话说,也许你的应用中根本不会出现不会飞的鸟,那还操那个心干什么?)3.在运行时检查逻辑错误,抛出异常或提示错误等。4.在逻辑非法的操作中使用static_assert(),保证编译期查错,个别禁止非法行为;(也就是在企鹅的飞行函数中加入一个错的判断)----------------------------------------------------------------2010.03.27问题描述:在Visual Studio 2005中,如何将代码转换为标准格式?解决方法:选定需要格式化的范围,在菜单中选择“编辑”->“高级”->“设置选定内容的格式”即可。快捷键为:CTRL+K,CTRL+F----------------------------------------------------------------2010.03.27问题描述:在Visual Studio 2005中,如何为主函数执行加入参数?解决方法:在菜单中选择“项目”->“属性”->“配置属性”->“调试”->"命令参数",加入参数即可。----------------------------------------------------------------2010.03.30问题描述:如何在启动命令行界面(cmd.exe)运行程序时,程序执行完毕后命令行不退出?解决方法:1. 在启动命令行的时候加入参数 /k 可以保持命令行不自动退出。如:cmd /k test.exe----------------------------------------------------------------2010.03.30问题描述:对一个区间进行排序的标准算法有哪些?都完成什么功能?解决方法:1.BidirectionalIterator partition(BidirectionalIterator first, BidirectionalIterator last, Predicate pred);完成区间[first,last)的不稳定二分,使满足pred(*iter)的元素都在左边,返回值是指向第一个不满足pred(*iter)==true的迭代器iter。2. BidirectionalIterator stable_partition(BidirectionalIterator first, BidirectionalIterator last, Predicate pred);完成区间[first,last)的稳定二分,使满足pred(*iter)的元素都在左边,返回值是指向第一个不满足pred(*iter)==true的迭代器iter。3. void nth_element(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last);void nth_element(RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, StrictWeakOrdering cmp);完成区间[first,last)上的不稳定二分,使区间[first,middle+1)内的任意元素i和区间[middle+1,last)内的任意元素j满足j<i==false(或cmp(j,i)==false),而且,middle位置的元素恰好是区间[first,last)全排后middle位置的元素。4. void partial_sort(RandomAccessIterator first, RandomAccessIterator first_n, RandomAccessIterator last);void partial_sort(RandomAccessIterator first, RandomAccessIterator first_n, RandomAccessIterator last, StrictWeakOrdering cmp);完成区间[first,last)上的不稳定二分,使区间[first,first_n)中的元素为[first,last)中的最小的(first_n-first)个元素,而且,[first,first_n)中的元素按升序排序(后一版本中,使用cmp为排序规则),[first_n,last)中的元素不排序。5. void sort(RandomAccessIterator first, RandomAccessIterator last);void sort(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering cmp);完成区间[first,last)的不稳定排序。(后一个版本使排序后的区间内相邻元素满足cmp(*(i+1),*i)==false(i为迭代器)。)6. void stable_sort(RandomAccessIterator first, RandomAccessIterator last);void stable_sort(RandomAccessIterator first, RandomAccessIterator last, StrictWeakOrdering cmp);完成区间[first,last)的稳定排序。(后一个版本使排序后的区间内相邻元素满足cmp(*(i+1),*i)==false(i为迭代器)。)----------------------------------------------------------------2010.04.05问题描述:为什么用私有继承不能实现运行时多态?问题原因:人民邮电出版社.徐惠民.2005年.《C++大学基础教程》.P246有以下语句:要实现运行时的多态,需要以下条件:必须通过指向基类对象的指针访问和基类成员函数同名的派生类成员函数;或者用派生类对象初始化的基类对象的引用访问和基类成员函数同名的派生类成员函数;派生类的继承方式必须是共有继承;基类中的同名成员函数必须定义为虚函数。解决方法:如上所述,私有继承和保护继承都不能实现运行时多态,要将继承方式改为公有继承,并将需要实现多态的成员函数修改为虚函数。----------------------------------------------------------------2010.04.07问题描述:为什么#include <stdlib.h>后报错“std命名空间中没有名为long labs(long)的函数”?问题原因:因为stdlib.h是C语言的函数,没有命名空间概念。解决方法:改用#include <cstdlib>,long labs(long)在其中的std命名空间内。(顺便说一句,全局命名空间中的labs仍然有效(long ::labs(long)),放心用您的。)----------------------------------------------------------------2010.04.09问题描述:如何在Visual Studio 2010里面设置全局引用目录(include)和库目录(lib)?解决方法:"View"->"Property Manager"(没看到蹦出来对话框?没错。它在左边的边栏里)->"Properties"(可以按里面的按钮,也可以在空白处右键)->"Configuration Properties"->"VC++ Directories"----------------------------------------------------------------2010.08.26问题描述:size_t是在哪个头文件中定义的?解决方法:在<cstddef>中定义,该文件定义了若干个标识符:类型:ptrdiff_t, size_t宏:NULL, offsetof----------------------------------------------------------------2010.08.27问题描述:system()函数是在哪个头文件中定义的?解决方法:在<cstdlib>中定义,该文件定义了getenv()和system()函数。----------------------------------------------------------------2010.08.28问题描述:<stdexcept>头文件中有哪些成员?解决方法:成员如下:domain_error Class The class serves as the base class for all exceptions thrown to report a domain error. invalid_argument Class The class serves as the base class for all exceptions thrown to report an invalid argument. length_error Class The class serves as the base class for all exceptions thrown to report an attempt to generate an object too long to be specified. logic_error Class The class serves as the base class for all exceptions thrown to report errors presumably detectable before the program executes, such as violations of logical preconditions. out_of_range Class The class serves as the base class for all exceptions thrown to report an argument that is out of its valid range. overflow_error Class The class serves as the base class for all exceptions thrown to report an arithmetic overflow. range_error Class The class serves as the base class for all exceptions thrown to report a range error. runtime_error Class The class serves as the base class for all exceptions thrown to report errors presumably detectable only when the program executes. underflow_error Class The class serves as the base class for all exceptions thrown to report an arithmetic underflow.----------------------------------------------------------------2010.08.31问题描述:在输入流中,如何把读到的一个字节放回到输入缓冲区中?解决方法:istream& istream.putback(char c);----------------------------------------------------------------2010.08.31问题描述:在输入流中,如何提取缓冲区第一个字符而不造成读取指针变化?解决方法:int istream.peek();----------------------------------------------------------------2010.08.31问题描述:在输入流中,如何读取一个以回车结尾的行字符串,而不读取回车?解决方法:istream& istream.get( char* buffer, streamsize num );istream& istream.get( char* buffer, streamsize num, char delim );----------------------------------------------------------------2010.08.31问题描述:istream.getline(char* buf, streamsize size)最多读取多少字节?解决方法:size-1。----------------------------------------------------------------2010.09.20问题描述:如何处理double类型的NaN数据?解决方法:1.#include <limits>using namespace std;bool numeric_limits<double>::has_quiet_NaNdouble numeric_limits<double>::quiet_NaNbool numeric_limits<double>::has_signaling_NaNdouble numeric_limits<double>::signaling_NaN2.#define NAN (0.0/0.0)#define IS_NAN(val) ((val)!=(val))----------------------------------------------------------------2010.09.23问题描述:有没有比较搞笑的模板使用方法?解决方法:有的是。1.template <typename T,template<typename> Comp=greater>class Select//没有实际作用,就是演示模板用法{public:T operator () (T* first, T* last){if (first>=last)return T();T val=*first++;Comp<T> comp;//注意:亮点!while (first!=last)if (!comp(val,*first))val = *first;return val;}};----------------------------------------------------------------2010.10.10_20'18问题描述:如何使用C++实现通用的“字符串转为其他类型”函数?解决方法:#include <sstream>template <typename T>T cast(const char* str){std::stringstream ss;ss << str;T val;ss >> val;return val;}----------------------------------------------------------------2010.10.14_10'09问题描述:在C++中能否直接引用C风格头文件?解决方法:在Linux下测试,可以直接引用<math.h>,内部函数位于全局命名空间。----------------------------------------------------------------2010.10.16_02'21问题描述:如何安装boost库?解决方法:在Windows上,根据文档向导所示:1. 启动Visual Studio 命令行,将文件夹cd到boost文件夹根目录2. 输入命令bootstrap,回车3. 输入命令bjam --prefix=D:\Libraries\boost --build-type=complete install,回车4. 耐心等待,卡住了也不要管,直至安装完成。在Linux上,根据文档向导所示:1. 开启一个终端,cd到boost文件夹根目录2. 输入命令./bootstrap.sh,回车3. 输入命令sudo ./bjam install,回车(需要系统权限)4. 耐心等待,直至安装完成----------------------------------------------------------------2010.10.17_15'23问题描述:在Visual Studio 2005中,为什么空项目不能调试?如何解决?问题原因:在空项目中不生成调试文件pdb,所以无法调试。解决方法:项目->属性->配置属性->链接器->调试->生成调试信息->是项目->属性->配置属性->C/C++->常规->调试信息格式->C7兼容项目->属性->配置属性->C/C++->优化->优化->禁用(参考:http://blog.163.com/cjp19900228@126/blog/static/12016225720105514314590/)----------------------------------------------------------------2010.11.13_18'41问题描述:下面的语句,为什么第一行不会报错?为什么第二行会报错?string string, str;string str1;问题原因:1. 第一行不会报错,是因为局部变量string是在类型名string之后出现的,不会导致类型名解析为变量,不会出错;2. str在变量string之后出现,但因为这种声明语法表示str的类型是变量string出现之前的类型名string,所以也不会出错;3. str1的声明,试图使用类型名string,但此时变量string已经覆盖了str1所处的作用域中所有其他的与string同名的元素,所以编译器认为str1前面的string是变量名,而不是类型名,因此出现声明错误;解决方法:1. 尽量不要以类型名命名变量,这样看起来很帅气,实际很危险;2. 在名称空间已经被污染之后,使用作用域操作符(::)来指明到底要用哪一个名称,如下所示:string string,str;std::string str1;::string str2;----------------------------------------------------------------2010.11.14_18'04问题描述:使用new int[10]能否初始化?解决方法:能,但只能进行默认初始化,语法为:new int[10]();如果试图用初值初始化(new int[10](3)),则编译报错。----------------------------------------------------------------2010.11.14_21'04问题描述:如何在Linux下使用boost库编写程序?解决方法:在Linux下,使用库文件需要在编译选项中指明所使用的库,所以只把库所在文件夹给出是没有用的。makefile中相关配置如下:# BOOST_INC_DIR: where the boost headers (ie. header directory "boost/") areBOOST_INC_DIR = /usr/local/include# BOOST_LIB_DIR: where the boost binary libraries areBOOST_LIB_DIR = /usr/local/lib# INC_BOOST: used to add all boost headers to include pathINC_BOOST = -I$(BOOST_INC_DIR)# LIB_BOOST: used to add all boost libraries to compile pathLIB_BOOST = -L$(BOOST_LIB_DIR) \-lboost_date_time \-lboost_filesystem \-lboost_graph \-lboost_math_c99 \-lboost_math_c99f \-lboost_math_c99l \-lboost_math_tr1 \-lboost_math_tr1f \-lboost_math_tr1l \-lboost_prg_exec_monitor \-lboost_program_options \-lboost_random \-lboost_regex \-lboost_serialization \-lboost_signals \-lboost_system \-lboost_test_exec_monitor \-lboost_thread \-lboost_unit_test_framework \-lboost_wave \-lboost_wserialization \exec : *.cppc++ *.cpp -o a $(INC_BOOST) $(LIB_BOOST)----------------------------------------------------------------2010.11.18_12'37问题描述:如何在一个局部作用域内,强制使用一组重载函数中的某一个?解决方法:使用函数的局部声明,根据C++的名字查找和作用域覆盖规则,将屏蔽掉重载函数名。具体实例如下:void print(char*);void print(int);void print(double);int test(){void print(int);print(30);//use void print(int)print(2.5);//use void print(int)}----------------------------------------------------------------2010.11.18_13'29问题描述:在#include <iostream>之后,如果需要使用istream或ostream,是否还需要单独#include <istream>或<ostream>?解决方法:不用。iostream类继承自istream和ostream,即如果我们能看到iostream类,就一定能看到istream类和ostream类,不用单独引用这两个相应的头文件。----------------------------------------------------------------2010.11.19_16'36问题描述:编译器如何确定拷贝构造函数和赋值运算符的选择?解决方法:A a; A b(a);//调用拷贝构造函数 或 A b=a;//仍然调用拷贝构造函数   A a; A b; b=a;//这样才能调用赋值运算符 ----------------------------------------------------------------2010.11.20_20'08问题描述:如何编写工具代码,得到一个数组的大小?解决方法:1. 使用常规方法,sizeof:#define ARRAY_LENGTH(arr) (sizeof(arr)/sizeof(arr[0]))2. 使用模板函数:template <typename T, size_t N>inline size_t ArrayLength(T (&arr)[N]) {return N;}----------------------------------------------------------------2010.11.21_14'21问题描述:在位域定义中,可否将同一字节内的不同位赋予不同的访问权限?解决方法:可以,示例如下:class BitField{public:unsigned char a:2;protected:unsigned char b:2;protected:unsigned char c:2;};//sizeof(BitField)==1;----------------------------------------------------------------2010.11.23_19'13问题描述:如何使用C++读取一个目录下的所有文件(夹)名?解决方法:使用操作系统目录命令和C++ system()函数,代码如下(Windows为例):system("dir /B > input.txt");ifstream fin("input.txt");cout << fin.rdbuf();fin.close();system("del input.txt");----------------------------------------------------------------2010.12.01_09'19问题描述:在继承层次中,如果基类定义了重载的虚函数,在派生类中能否只覆盖其中一个重载,而复用其他重载?解决方法:能。只要在派生类中public区块指定using Base::FuncName(没有括号),再重载需要的形式即可。代码如下:class A{public:virtual void func() {cout << "A::func()" << endl;}virtual void func(int i) {cout << "A::func(" << i << ")" << endl;}};class B1: public A{public:void func() {cout << "B1::func()" << endl;}};class B2: public A{public:using A::func;void func() {cout << "B2::func()" << endl;}};int main(){A a;a.func();a.func(1);B1 b1;b1.func();//b1.func(2); //errorB2 b2;b2.func();b2.func(3);}输出如下:A::func()A::func(1)B1::func()B2::func()A::func(3)----------------------------------------------------------------

?

读书人网 >C++

热点推荐