《程序员》杂志专家门诊C/C++问题

babysloth 2002-04-19 11:17:48
下面是《程序员》杂志第5期中专家门诊部分的C/C++问题,我整理了几个,大家能否看看有没有什么问题。

由于这次时间仓促,没有及时与大家商量,非常抱歉。以后希望大家多提建议,推荐您认为好的问题,共同学习。

----------------------------------------------

需要在 p = new xxx()之后检查NULL吗?

按现行标准,如果内存分配失败,则会抛出std::bad_alloc异常。但有些编译器仍遵循以前的方式:返回0,例如Microsoft Visual C++。不过从VC7开始,CRT仍采取这样的方式,但VC中的C++标准库则支持抛出异常之一标准方式。详细情况请见MSDN。

另外,标准委员会为了与以前保持一致性,也提供了不抛出异常的方式:

xxx *p = new (nothrow) xxx;

这时就不妨用assert(p)。

相关问题在Effective C++上有非常精彩的描述,请参考。


----------------------------------------------



如何安全地将多态指针放进STL容器?

class A{};
class C: public A{};
// 以vector为例,如果
vector<A*> vec;
vec.push_back(new C());

问题出现如何对容器中的指针进行管理上,假如直接把指针放到容器里,然后在进行删除元素操作和容器的析构器中释放元素指向的内存,听起来似乎井井有条,但是如果一个容器中有多个元素指向同一个对象或者多个指向同一个对象的元素被包含到多个容器中,就会带来一片混乱


那么用标准库中的auto_ptr来管理指针又会如何呢?情况可能会更糟,不但老问题不能解决,还带来了新问题,auto_ptr只是简单地将指针的管理权在对象之间转移,假如在对容器进行操作的算法中将元素的管理权交给了临时对象,那么当算法完成后临时对象将自动地释放该元素指向的内存,结果将不堪设想。毕竟,auto_ptr是典型的“一拷就坏(Copy Destructive)”。

有一种解决办法是专门用一个容器来保存所有的动态对象,只有该容器可以删除对象,其他容器只保留指向这些对象的指针。当然这种做法比较烦。另一种简单的方法是利用Boost库(介绍见《程序员》2002年3月号的《走进Boost》一文)中的shared_ptr。

#include <list>
#include <boost/shared_ptr.hpp>
class A{};
class C: public A{};

void g()
{
typedef boost::shared_ptr<A> element_type;
typedef std::list<element_type> list_type;

list_type ll;
ll.push_back(element_type(new C));
}

这个比auto_ptr复杂得多的东东管理的是对象的引用计数,当计数为0时自动释放内存,呵呵,真是个好管家。


----------------------------------------------


一个std::string对象,要把这个对象两端多余的空格去掉,怎么办?

可以利用string的成员函数find_first_not_of和find_last_not_of:

#include <iostream>
#include <string>

template <class T> void trim(std::basic_string<T>& s)
{
const char c = ' ';
s.erase(0, s.find_first_not_of(c));
s.erase(s.find_last_not_of(c) + 1);
}

void main()
{
using namespace std;
string str(" 123 456 789 ");
trim(str);
cout << str << '$' << endl;
return;
}

如果字符串非空部分很长的话,上面的find_last_not_of显然缺乏效率,我们可以把trim函数改写为:

template <class T> void trim(std::basic_string<T>& s)
{
const char c = ' ';
s.erase(0, s.find_first_not_of(c));
basic_string<T>::reverse_iterator i =
std::find_if(s.rbegin(), s.rend(),
std::bind2nd(std::not_equal_to<T>(), c));
s.erase(i.base(), s.end());
}

不知道是否还有更好的方法。

----------------------------------------------
...全文
23 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
Elminster 2002-04-23
  • 打赏
  • 举报
回复
关于问题二,Matt Austern 在 CUJ Forum 上专文讨论过,相当详细。
关于问题三,嗯 …… 我想能不能讨论一下扩展情况?比如 string 两头既有空格又有‘\t’制表符,怎么把它们去掉?或者更一般些,给定一个字符集,将 string 两头在这个字符集中的字符都去掉?
hcpp 2002-04-23
  • 打赏
  • 举报
回复
领教领教。
babysloth 2002-04-23
  • 打赏
  • 举报
回复
谢谢大家的参与。
cber 2002-04-23
  • 打赏
  • 举报
回复
Elminster() :
对于问题三,在我上面给出的CppTips中已经由James Kanze搞定了,你可以去看看上面那一长串代码
>KANZE: James Kanze <kanze@gabi-soft.de>

>Not really. It doesn't consider other types of white space, nor
>other types of char.

Winner_Li 2002-04-22
  • 打赏
  • 举报
回复
Good!!
maoliao 2002-04-22
  • 打赏
  • 举报
回复
save!
xjl930 2002-04-22
  • 打赏
  • 举报
回复
STL的东西还是很值得探讨的,谢谢小懒虫虫精彩的帖子,收藏!!
jjyin7806 2002-04-22
  • 打赏
  • 举报
回复
GOOD
招RD和QA 2002-04-22
  • 打赏
  • 举报
回复
gzer
nicholas_87 2002-04-21
  • 打赏
  • 举报
回复
saved...
挺拔的劲松 2002-04-21
  • 打赏
  • 举报
回复
sc
vcmfc 2002-04-20
  • 打赏
  • 举报
回复
我的思跟是这样的,C中有个函数,名给忘了,也就是在一个char*上拷贝指定东东,估计没出异常安全,所以就是*p++加入API,不过代码还是比你多,你的最精练,对于string,你运用的好熟练,看来得闭关。
cber 2002-04-20
  • 打赏
  • 举报
回复
TITLE: trimming a standard string

(Source: comp.lang.c++.moderated, 18 Sep 2001)

WILSON: Bryan Wilson

> > I am new to C++ using MS Visual C++ 6.0 and trying to create a dll
> > to parse chunks from a flat .ASC file into a tab delimited .txt
> > file with leading and trailing spaces trimed off. Could someone
> > please show me an example of how to write the trim functionality??

FRITZSCHE: Albrecht Fritzsche <albrecht.fritzsche@alfabet.de>

> The std::string class already offers you enough functionality:
>
> std::string shortenString(const std::string& str) // untested code!!
> {
> std::string::size_type first = str.find_first_not_of(" ");
> std::string::size_type last = str.find_last_not_of(" ");
> return str.substr(first, last-first+1);
> }
>
> should give you a trimmed string

KANZE: James Kanze <kanze@gabi-soft.de>

Not really. It doesn't consider other types of white space, nor
other types of char.

There is a function in std::ctype that you'd expect to give you what
you need: scan_is. Regretfully, it doesn't work with iterators, only
charT*, so we are a bit handicapped. However, we can use std::find_if
by simply defining an appropriate predicate:

template< std::ctype_base::mask type , typename charT = char >
class Is : public std::unary_function< charT , bool >
{
public:
explicit Is( std::locale const& l )
: m_ctype( std::use_facet< std::ctype< charT > >( l ) )
{
}
bool operator()( charT ch ) const
{
return m_ctype.is( type , ch ) ;
}
private:
std::ctype< charT > const&
m_ctype ;
} ;

Given this, trim becomes just a simple return statement:

template< typename stringT >
stringT
trim( stringT const& s , std::locale const& l = std::locale() )
{
return
std::find_if(
s.begin() , s.end() ,
std::not1( Is< std::ctype_base::space ,
typename stringT::value_type >( l ) ) )
== s.end()
? stringT()
: stringT(
std::find_if(
s.begin() , s.end() ,
std::not1( Is< std::ctype_base::space ,
typename stringT::value_type >( l )
) ) ,
std::find_if(
s.rbegin() , s.rend() ,
std::not1( Is< std::ctype_base::space ,
typename stringT::value_type >( l )
) ).base() ) ;
}

OK, so the statement's a bit long. But the logic in it is actually
very simple, once you get through the cruft due to namespaces and the
template syntax. (Welcome to the wonderful world of generic
programming:-).)
x_zj 2002-04-20
  • 打赏
  • 举报
回复
to vcmfc:
那个函数是: strdup。
vcmfc 2002-04-19
  • 打赏
  • 举报
回复
最后一期,我是热衷于使用*p++的C方式来处理,高效安全。


这东东用STL,感觉就像用大炮打蚊子。
twist 2002-04-19
  • 打赏
  • 举报
回复
收藏
cber 2002-04-19
  • 打赏
  • 举报
回复
不错,不过我记得最后那个问题在CppTips上面有一个更据弹性的做法,但很复杂。你给出的那个做法差不多可以在大部分情况下使用了。
babysloth 2002-04-19
  • 打赏
  • 举报
回复
不用这样啊,老哥,呵呵。
就算是char*,恐怕也不容易,因为还涉及内存管理的问题。
vcmfc 2002-04-19
  • 打赏
  • 举报
回复
上面我说错了,是去掉string,而我以为是char*,真没长眼睛,收回我的话。

babysloth还是厉害,不得不佩服。
ljf1107 2002-04-19
  • 打赏
  • 举报
回复
不错!
加载更多回复(2)
【资源说明】 基于c++和qt实现的医院排队叫号系统源码+报告(课程设计).zip基于c++和qt实现的医院排队叫号系统源码+报告(课程设计).zip基于c++和qt实现的医院排队叫号系统源码+报告(课程设计).zip基于c++和qt实现的医院排队叫号系统源码+报告(课程设计).zip基于c++和qt实现的医院排队叫号系统源码+报告(课程设计).zip基于c++和qt实现的医院排队叫号系统源码+报告(课程设计).zip 基于c++和qt实现的医院排队叫号系统源码+报告(课程设计).zip 题目 某医院普通门诊拥有科室 15 个,每个科室值班医生 3 人;B 超室 1 个,有 3 台 B 超 机。现需设计一个叫号系统,通过挂号次序,安排每个科室叫号顺序,各科室在诊断完 病人后,根据其是否开具 B 超检查要求,安排 B 超室的叫号顺序,并在所有过程中,记 录每位医生所看的病人及其听诊时间。 (1)需实现挂号过程,医生就诊过程。 (2)显示各科室、B 超室目前排队情况。 (3)查看各医生就诊的所有病人。 2.2 软件功能 (1)挂号功能。根据用户输入的个人信息以及选择的科室和医生进行挂号。考虑到实 际生活中病人就诊可能会有医生选择偏好,也可能没有这种偏好,当没有医生偏好时,叫号 系统自动将病人安排到当前空闲的医生处; (2)医生就诊功能。医生就诊功能实际上就是病人在指定时间段占用医生工作时间的 过程,可以用随机数模拟每个挂号病人需要的听诊时间和 B 超时间(其中 B 超时间可能等于 0),手动模拟时间流逝,进而模拟医生就诊过程; (3)显示各个科室、B 超室目前的排队情况。对于各个科室和 B 超室,叫号系统能够 实时显示当前排队人数。而对于每个医生和每个 B 超机,则实时显示当前就诊或 B 超病人的 编号和姓名,符合现实生活中医院叫号信息大屏的设定; (4)查看各医生就诊的所有病人。对于每一个医生,当其完成一位病人的诊断后,都 将该病人的基本信息以及就诊时间记录在该医生的日志文件中,可以实时查询。 上述四项功能都采用面向对象的方法通过 C++语言程序结合 QT 框架实现,界面分为三 个子界面,分别实现挂号系统、排队情况和记录查询功能,后续会进行详细介绍。 【备注】 1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载使用体验! 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈!
ASP.NET常见问题集锦.zip . .. .net中中文乱码问题解决.txt ADO.NET 与 XML:双剑合壁,威力强大.doc ASP.NET HTTP 运行时.doc ASP.NET ViewState 初探.doc ASP.NET Web 方法中的 XmlElement 参数的功能.d ASP.NET 中 Cookie 的基本知识.doc ASP.NET 页面对象模型.doc asp.net200问-专家门诊—ASP.NET开发答疑 ASP.NetWebPage深入探讨.txt ASP.NET中为DataGrid添加合计字段.doc ASP.NET中实现DataGrid数据排序.doc asp.net中的弹出对话框.doc ASP.NET中自定义控件的创建和使用.doc ASP.NET实现用户在线检测的类源码.txt ASP.NET常见问题集锦.zip ASP.NET弹出式日历选择控件的实现.doc ASP.NET程序中常用的三十三种代码.txt ASP.NET页面间数据传递小结.doc ASPNETXML深入编程.pdf C Primer Plus 5th.chm C#中结构与类的区别.doc C#复习.txt C#实现Web文件上传的两种方法.doc C#排序算法大全.txt C#编程规范.doc C#语言参考.doc Code.doc C#中的“装箱”与“拆箱”.txt Datagrid分页、排序、删除代码.txt DataList分页、增加、删除、修改实例.doc is as override示例.txt JA_ASP lecture_UML MS Press - Programming Microsoft.Net.chm NET 技术交流与实际应用.ppt net窗体身份验证方案.doc OOAD OOAD.doc Oreilly - C#.Net Programming 2nd Edition--ne Sort.cs treeview问题.txt Visual Basic .NET 和 Visual C# .NET 程序员需 vs.net安装部署深入研究.doc WEB_APP_E_BOOK.pdf XML编程从入门到精通.pdf 《ASP.NET完全入门》 一个Web文件上传的C#源代码.doc 为 ASP.NET Datagrid 创建自定义列.doc 为DataGrid写一个DropDownListColumn.txt 从 ASP.NET 服务器控件插入客户端脚本.doc 从 ASPX 页面进行 Web 服务调用时的性能考虑.do 使用 .NET 框架轻松开发完美的 Web 窗体控件.do 使用 TreeView IE Web 控件.doc 关于ASP.Net中的时间处理.txt 关于上下文.doc 创建可分页、可排序的 DataGrid.doc 创建用于 ASP.NET 的分页程序控件.doc 创建用于ASP.NET的分页控件.txt 利用 ASP.NET 创建多页自定义报表.doc 利用属性扩展元数据.doc 在 ASP.NET 中实现会话状态的基础.doc 在ASP.NET程序中实现上传下载文件.doc 复合 Web 控件示例(2.0).doc 如何在ASP.Net中把图片存入数据库.txt 如何在DateTime字段里只存储日期部分?.txt 如何用.NET创建Windows服务.doc 委托与事件.doc 学生选课系统事例(老师).txt 学生选课系统示例(自己).txt 开发和使用自定义服务器控件(2005).doc 开发组件.doc 归并排序,快速排序,冒泡算法,二叉查找树.doc 微软C编程精粹.doc 探讨 ASP.NET 的可伸缩性.doc 提高ASP.Net应用程序性能的十大方法.doc 无废话XML.pdf 概念.txt 求最大最小值示例.txt 用ASP.NET创建自定义文本框.doc 电话卡销售电子商务平台系统.doc 笔记.txt 类结构分析.doc 索引器例子.txt 翻译C#.txt 老师quicksort算发(无相等的两个元素).txt 老师quicksort算发(考虑相等的两个元素).txt 老师的学生考试系统改造结果.txt 自定义控件.doc 认识Web.config文件.doc 设计模式迷你手册.chm 设计模式(搞笑).doc 转意字符.txt 进入 ASP.NET 世界 - 第 1 部分:应用程序规划 进入 ASP.NET 世界 - 第 2 部分:使用 SQL Serv 面向对象设计(OOD)思想(C#) - c-c++ - CSDN

69,379

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧