《程序员》杂志专家门诊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());
}

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

----------------------------------------------
...全文
66 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)
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 Altium Designer 18是一款功能丰富的电子设计自动化工具,其集成了电路原理图绘制、PCB布局规划、三维视图展示、电路仿真分析以及生产文件生成等多项核心功能,为电子工程师们提供了一个全面的硬件设计解决方案。该软件的官方中文指导材料系统地阐述了从项目初始阶段到最终完成的全过程操作方法。 在“AD18 官方中文指导材料”中,使用者可以掌握以下核心内容要点: 1. **系统配置与界面认知**:熟悉Altium Designer 18的工作平台,涵盖菜单选项、工具栏配置、工作区域安排,以及个性化工作界面的设定方法。 2. **项目创建流程**:掌握如何建立新的项目工程,包括工程参数配置、项目模板选取,以及项目文件的添加操作。 3. **电路图绘制技术**:学习电路原理图的绘制流程,包括元件库的维护管理、元件放置技巧、连接线路绘制、属性编辑操作,以及网络表的自动生成方法。 4. **元件库构建与管理**:了解如何建立自定义元件库,执行元件的导入与导出任务,以及利用Altium Designer自带的元件资源库。 5. **PCB布局设计方法**:掌握PCB设计的基本准则,如元件布局策略、布线技巧、层叠结构调整、布线规则优化,以及冲突检测与短路处理技术。 6. **设计规范与约束条件**:理解设定设计规范和电气约束条件的关键性,包括间距参数设定、焊盘尺寸规格、过孔尺寸要求等,以及运用规则检查进行设计验证的流程。 7. **三维模型整合应用**:学习如何将三维模型与PCB设计内容相结合,以实现更为直观的机械配合验证。 8. **电路性能仿真技术**:掌握使用Altium Des...
源码链接: https://pan.quark.cn/s/a4b39357ea24 ### 接口测试知识要点说明 #### 一、接口测试的定义及分类 1. **概念阐释**: - 接口测试作为软件测试的关键环节,主要对系统之间的交互点进行验证。 - 它旨在核实接口的正确性、稳定性和功能性,保障各个系统组件能够依照预期执行交互操作。 2. **实施情境**: - 适用于多系统联合开发的环境。 - 适用于包含多个子系统的复杂应用系统开发过程。 3. **适用范围**: - 为其他系统提供支持的底层基础架构系统。 - 负责协调中心服务的系统架构。 4. **分类标准**: - **模块接口测试**:通常作为单元测试的一部分,适用于独立构建的功能模块。 - **Web接口测试**: - **服务端接口测试**:针对客户端与服务器端之间的接口进行验证。 - **外部接口测试**:对第三方提供的接口进行测试,例如支付平台提供的授权登录接口。 5. **测试角度**: - **接口功能验证**:核实接口功能是否满足预期要求。 - **接口性能评估**:衡量接口的处理能力及响应时间。 - **接口稳定性考察**:检测接口在长时间运行中的表现情况。 - **接口安全检测**:确保接口能够抵御非法访问或数据篡改。 6. **测试手法**: - **参数细致测试**:深入测试接口的输入参数和输出结果。 - **场景模拟测试**:依据实际业务场景进行测试验证。 #### 二、接口测试的详细流程 1. **测试规划**: - 明确测试范围、目标及所需资源。 - 规划测试策略,选择适宜的工具和技术手段。 2. **测试用例设计**: - 依据需求文档和接口规格文档设计测试用例。 - 覆...
内容概要:本文研究基于遗传算法(GA)与粒子群算法(PSO)相结合的无人机三维路径规划方法,旨在解决无人机在复杂三维环境中避障与路径优化的关键问题。通过构建包含障碍物、威胁区域等约束的三维仿真环境,系统实现了GA与PSO两种智能优化算法的Matlab代码,并对其在路径规划中的性能进行全面对比分析,重点关注路径长度、飞行安全性、算法收敛速度等核心指标。研究充分利用GA的全局搜索能力与PSO的快速局部收敛特性,提出一种混合优化策略,有效克服单一算法易陷入局部最优或收敛缓慢的缺陷。文中不仅详细阐述了算法的设计流程、数学模型与实现细节,还提供了完整的仿真结果,验证了所提混合方法在复杂动态场景下的优越性、有效性和鲁棒性,为无人机自主导航提供了可靠的理论依据和技术方案。; 适合人群:具备一定Matlab编程基础和优化算法理论知识,从事无人机系统设计、智能控制、路径规划、人工智能应用等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于城市峡谷、山区、灾害救援等复杂三维环境中的无人机自主避障与最优任务路径规划;②为智能优化算法(GA、PSO及其混合策略)的学习、性能对比与工程化应用提供详实的实践案例和代码参考;③服务于高校科研教学、算法原型快速复现、以及在此基础上的进一步改进与创新研究。; 阅读建议:建议读者结合所提供的Matlab代码进行仿真运行与调试,深入理解两种算法的参数设置、适应度函数设计及路径生成机制,可通过修改环境地图、增加动态障碍物或调整优化目标函数等方式进行扩展性研究,以深化对算法本质和应用场景的理解。

70,039

社区成员

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

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