C++编程新手容易犯的 10 种编程错误

点击蓝字

ac29df264a0972e16df49d8795790e3b.png

关注我们

因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享

来源于网络,侵删

公司每年都会有一定的人员流动,相应地也会招一些应届生补充进来,指导应届生已经成为老员工的必修课了。

平日里会我们会经常帮新人排查代码中的问题,在此过程中发现了 C++ 新手容易犯的一些编程错误,在此简单的总结一下,给新人们提供一个参考。

1、有些关键字在 cpp 文件中多写了

对于 C++ 类,一些关键字只要写在 .h 中就好,cpp 中就不用再加上了,比如 virtual、static 等关键字,如果在 cpp 中多写,编译器会报错。比如如下的虚接口与静态成员变量的定义,只要在头文件中声明就可以了。

class shape
{virtual Draw();//...static int nLevel;
}

2、函数参数的默认值写到函数实现中了

带有参数默认值的函数,默认值是加在函数声明处的,函数实现处的参数是不需要带上的。为了方便查看代码,在函数实现处的参数中,将默认值注释起来。正确的做法是,头文件中有默认值:

BOOL CreateConf( const CString& strConfName, const BOOL bAudio = FALSE );
在函数实现处的参数中不用添加默认值:
BOOL CreateConf( const CString& strConfName, const BOOL bAudio/* = FALSE*/ );
{// ......
}

3、在编写类的时候,在类的结尾处忘记添加 ";" 分号了

在类的结尾处忘记添加分号,编译会报错,新人们有可能找了半天也没找出引起编译错误的原因。其实很简单,在类的结尾处忘记添加分号了。

class Shape
{// ...
};

4、只添加了函数声明,没有函数实现

在添加类的函数时,只在类的头文件中添加了函数声明,但在 cpp 中却没有添加函数的实现。如果其他地方调用到该函数,在编译链接的时候会报unresolved external symbol错误。因为没有实现,所有没有供链接使用的 obj 文件。

5、cpp 文件忘记添加到工程中,导致没有生成供链接使用的 obj 文件

在添加 C++ 类时,我们一般会添加 .h 头文件和一个 .cpp 源文件。结果忘记把 .cpp 文件添加到工程中了,即没有参与编译,没有生成供链接使用的 obj 文件。如果有代码调用到该 C++ 类的接口,则在编译链接的时候会报unresolved external symbol错误,即链接不到该 C++ 类对应的接口。

6、函数中返回了一个局部变量的地址或者引用

在函数中返回了一个局部变量的地址或者引用,而这个局部变量在函数结束时其生命周期就结束了,内存就被释放了。当外部访问到该变量的内存,会触发内存访问违例的异常,因为该变量的内存已经释放了。比如如下的错误代码:

char* GetResult()
{char chResult[100] = { 0 };// ......return chResult;
}

7、忘记将父类中的接口声明 virtual 函数,导致多态没有生效

代码中本来要借助于 C++ 多态的虚函数调用,调用子类实现的接口,结果忘记在父类中将对应的接口声明为 virtual,导致没有调用到子类实现的函数。一定要记住,要实现多态下的函数调用,父类的相关接口必须声明为 virtual。

class Shape()
{// ...virtual void Draw();// ...
}

8、该使用双指针的地方,却使用了单指针

有时我们需要调用一个接口去获取某些数据,接口中将数据拷贝到传入的参数对应的内存中,此时设计参数时会传入指针或引用。我们在调用GetData 之前定义了结构体指针p,并 new 出了对应的结构体对象内存,应该在定义 GetData 接口时应该使用双指针(指针的指针)的,结果错写成了单指针。

有问题的代码如下:

struct CodecInfo     // 编码信息
{int nFrameRate;// ...
}CodecInfo* pInfo = new CodecInfo;GetAudioCodecPtr()->GetCodecInfo(pInfo);   // 调用AudioCodec::GetCodecInfo获取编码信息AudioCodec::GetCodecInfo( CodecInfo* pInfo)  // 此处的参数不应该使用单指针
{memcpy(pInfo, m_codecInfo, sizeof(CodecInfo));
}

上面中的AudioCodec::GetCodecInfo接口的参数不应该为单指针,应该用双指针,修改后的代码应该如下:

AudioCodec::GetCodecInfo( CodecInfo** pInfo)  // 此处的参数类型使用双指针
{memcpy(*pInfo, m_codecInfo, sizeof(CodecInfo));
}

9、发布 exe 程序时,忘记将 exe 依赖的 C 运行时库和 MFC 库带上

比如新人用 VS-MFC 库编写一个测试用的工具软件,结果在发布 release 版本程序时,没有将程序依赖的 C 运行时库带上,导致该工具软件在某些电脑中启动报错,提示找不到 C 运行时库:

因为程序中依赖了动态版本的运行时库和 MFC 库,在发布程序时要将这些库带上。有些系统中没有这些库,程序启动时就会报找不到库,就会启动失败。

10、应该使用深拷贝,却使用了浅拷贝

本来应该要进行深拷贝的,却使用了浅拷贝(直接赋值),导致另个不同生命周期的 C++ 对象指向了同一块内存,一个对象将内存释放后,另一个对象再用到这块内存,就造成了内存访问违例,产生异常。

有个经典的 C++ 笔试题,让我们实现 String 类的相关函数,其主要目的就是用来考察对深拷贝与浅拷贝的理解的。题目中给出 String类的声明:

class String{
public:String();String(const String & str);String(const char* str);String& operator=(String str);char* c_str() const;~String();int size() const;
private:char* data;
};

让写出上述几个函数的内部实现。这些函数的实现代码如下:

//普通构造函数  
String::String(const char *str)
{if (str == NULL){m_data = new char[1];// 得分点:对空字符串自动申请存放结束标志'\0'的,加分点:对m_data加NULL判断  *m_data = '\0';}else{int length = strlen(str);m_data = new char[length + 1];// 若能加 NULL 判断则更好strcpy(m_data, str);}
}// String的析构函数  
String::~String(void)
{delete[] m_data; // 或delete m_data;  
}//拷贝构造函数  
String::String(const String &other)// 得分点:输入参数为const型  
{     int length = strlen(other.m_data);m_data = new char[length + 1];// 若能加 NULL 判断则更好  strcpy(m_data, other.m_data);
}//赋值函数  
String & String::operator = (const String &other) // 得分点:输入参数为const型  
{if (this == &other)//得分点:检查自赋值  return *this; if (m_data)delete[] m_data;//得分点:释放原有的内存资源  int length = strlen(other.m_data);m_data = new char[length + 1];//加分点:对m_data加NULL判断  strcpy(m_data, other.m_data);return *this;//得分点:返回本对象的引用    
}

0e3c4d2dd936578251523a9266f1b894.gif

如果你年满18周岁以上,又觉得学【C语言】太难?想尝试其他编程语言,那么我推荐你学Python,现有价值499元Python零基础课程限时免费领取,限10个名额!
▲扫描二维码-免费领取

戳“阅读原文”我们一起进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337133.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux上C语言程序编译过程详解

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删本文将介绍如何将高层的C/C语言编写的程序转换成为处理器能够执行的二进制代码的过程,包括四个步骤:预处理(P…

C语言,动图展示十大经典排序算法

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删以前也零零碎碎发过一些排序算法,但排版都不太好,又重新整理一次,排序算法是数据结构的重要部分,…

java ee各类组件_在Java EE组件中使用骆驼路线

java ee各类组件从现在开始我一直在与Camel合作,我真的很喜欢它的简单性。 在Java EE之上使用它一直是一个挑战,我最近发表了一篇关于如何做到这一点的演讲,而在Java EE中引导Camel的不同方法实际上建议使用WildFly-Camel Subsystem 。 在正在…

5gnr帧结构特点有哪些_真空离子束刻蚀设备的结构特点有哪些

离子束刻蚀设备有立式、卧式两种结构。通常情况下,该设备以卧式的结构居多,因为采用卧式结构的话,离子源发出的离子束为水平喷射方向,大部分的刻蚀溅射物将落在真空室的底部,可在一定程度上将溅射材料的重新沉积减少。…

老了就不能编程?大龄程序员在线“辟谣”:15 年后,我变得更好了

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删几年前,Quora 上的一个提问在程序员圈内掀起热议:“随着年龄的增长,人们会对编程失去兴趣吗?预计…

wildfly管理控制台_WildFly管理控制台已更新–请求反馈

wildfly管理控制台红帽JBoss企业应用程序平台(EAP)和WildFly具有共生关系 。 简而言之,红帽JBoss企业应用程序平台(JBoss EAP)保留了WildFly社区项目(以前称为JBoss Application Server)的所有创…

性能测试中脚本怎么写_脚本在流程中的性能影响

性能测试中脚本怎么写我们经常看到人们出于各种目的而使用脚本(例如,在服务任务,执行侦听器等中)。 使用脚本和Java逻辑通常很有意义: 它不需要打包到jar中并放在classpath上 它使流程定义更易于理解:无需…

超炫酷的C语言技巧

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删C语言常常让人觉得它所能表达的东西非常有限。它不具有类似第一级函数和模式匹配这样的高级功能。但是C非常简单,并且仍然有一些非常…

java8默认垃圾收集器_Java 8中最快的垃圾收集器是什么?

java8默认垃圾收集器OpenJDK 8具有几种垃圾收集器算法,例如Parallel GC , CMS和G1 。 哪一个最快? 如果默认GC从Java 8中的并行GC更改为Java 9中的G1(当前建议),将会发生什么? 让我们对其进行基…

u盘启动 联想一体机_联想Y430pAT-ISE(H)U盘安装Win7系统教程

最近听到有人在问联想Y430pAT-ISE(H)笔记本安装WIN 7系统的方法,联想Y430pAT-ISE(H)笔记本从发行到现在也快5年了,不过有人在问该电脑安装系统就说明有人还在使用,关于联想Y430pAT-ISE(H)安装Win 7系统的方法有很多,不过大多过时了…

收藏|C语言常用的一些转换工具函数!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删1、字符串转十六进制代码实现&#xff1a;void StrToHex(char *pbDest, char *pbSrc, int nLen) {char h1,h2;char s1,s2;int i;for (i0; i<n…

apache camel_学习Apache Camel –实时索引推文

apache camel在大多数软件开发项目中&#xff0c;有一点需要使应用程序开始与其他应用程序或第三方组件通信。 无论是发送电子邮件通知&#xff0c;调用外部api&#xff0c;写入文件还是将数据从一个地方迁移到另一个地方&#xff0c;您都可以推出自己的解决方案或利用现有框架…

让你不再害怕指针——C指针详解(经典,非常详细)

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删前言:复杂类型说明要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型…

C语言实现可写入文件的账号密码登录系统

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删账号登录系统在很多系统设计时都时必不可少的&#xff0c;今天这个登录系统功能较全&#xff0c;可以注册&#xff0c;登录&#xff0c;找回密码…

一文搞懂 | Linux 内核的 4 大 IO 调度算法

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删Linux 内核包含4个IO调度器&#xff1a;Noop IO schedulerAnticipatory IO schedulerDeadline IO scheduler CFQ IO scheduler。anticipatory, 预…

众神进入瓦尔哈拉_一时冲动:“通往瓦尔哈拉之路的冒险”

众神进入瓦尔哈拉通过所有有关Java 9和Project Jigsaw的讨论&#xff0c;我们不应忽视Java的另一重大变化。 希望在第10版或第11版中&#xff0c; Valhalla项目能够实现并介绍价值类型和专业化。 那么&#xff0c;这是什么一回事&#xff0c;项目进展如何&#xff0c;面临什么…

当电子工程师十余年,感慨万千!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删当电子工程师也一些年头了&#xff0c;不算有出息&#xff0c;环顾四周&#xff0c;也没有看见几个有出息的。回顾工程师生涯&#xff0c;感慨万…

面试大全 | C语言高级部分总结,2.6万字长文

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删一、内存大话题1.0、内存就是程序的立足之地&#xff0c;体现内存重要性。1.1、内存理解&#xff1a;内存物理看是有很多个 Bank&#xff08;就是…

程序如何运行,编译、链接、装入?

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删一、地址概念和程序如何运行在多道程序环境下&#xff0c;要使程序运行&#xff0c;必须先为之创建进程。而创建进程的第一件事&#xff0c;便是…

NSA:建议从 C/C++ 切换到内存安全语言

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删美国国家安全局&#xff08;NSA&#xff09;发布了一份指南&#xff0c;旨在帮助软件开发商和运营商预防和缓解软件内存安全问题。其鼓励组织将编…