百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

C++编程一些常见问题(三) c++编程遇到的问题及解决方案

liebian365 2024-10-31 15:16 12 浏览 0 评论

21 new 与delete new[]/delete [ ]

(使用new与delete 与malloc不同之处在于 new分配内存 在析构函数中delete)

22 区分new 的三种形态

new operator

operator new

placement new

平常使用时 new operator

当时调用过程中 隐藏了 operator 和 placement的调用

重中之重的类

23 明确class和struct的区别

初始化问题

在没有定义构造函数之前,可以用大括号初始化

定义了以后就不能大括号初始化了

class只有成员名全部是public的情况下,才可以用大括号初始化

类的初始化问题

C c { 0,0};

数组的初始化

int *a = new int[3] {1,2,3};

成员变量初始化

class X

{

int a[4];

public:

x():a{1,2,3,4}

{

}

};

//vector的初始化

vector<string> Vs = {"first","second","third"};

map singers =

{{"Lady Gaga", "1+12345"},{"Lady Gaga", "1+12345"}};

关于默认访问权限

class中的默认访问权限是private的

而struct中的访问权限是public

关于默认继承方式

class中的继承方式是private继承

而在struct中的继承方式是public继承

24 C++悄悄做的事

所有的类都会有一个外号

“big three”

一个或者多个构造函数 +一个析构函数 +一个拷贝构造函数

面向对象的三座大山之一

即使没有声明对象,也会存在编译器会自动生成三个函数,成为默认构造函数,默认析构函数,默认拷贝构造函数

C++11中,标准引入了两个指示符delete和default,以便让程序员自行决定需要编译为我们偷偷生成这些函数,delete告诉编译器不产生这个函数,default告诉编译器产生这个函数

CEmpty中包含一个字节 分配 一个字节

25 首选初始化列表实现类成员的初始化

构造函数实现对类的初始化

尽量使用初始化列表

Cstudent::Cstudent(string name,int age,int id):

m_name(name)

,m_age(age)

,m_ID(id)

{

}

例如 :

对const 对象初始化 只能用列表

如果B类中有A类的成员变量只能够用列表初始化

26 明智的拒绝对象的复制操作

例如假设有一个高校的学生财务管理系统,因为每个学生都是一个独一无二的个体,绝对不会存在所有信息一模一样的情况,因此就不能存在一个学生的信息复制给另外一个学生的情况

怎么做呢

只声明不定义是一个好方法,即将类的相应的拷贝构造函数、赋值操作声明为private

并且不给出实现

27(*) 小心自定义构造函数

在声明类体系的时候 编译器会偷偷的声明 bigThree 其中拷贝构造函数和赋值函数都是用于对象拷贝的

所以统称为拷贝函数

编译器在生成拷贝函数会对所有的类一视同仁,不会特殊处理,他只是简简单单的降原对象的每个Non-static数据拷贝到对象中,即所谓浅拷贝

如果类中有动态内存分配,对象中包含资源,问题就会产生,此时需要用到深拷贝

class Cstring

{

public:

Cstring();

Cstring(const char *data);

private:

char *m_pdata;

int m_nsize;

};

Cstring strSrc("Hello everyone!");

Cstring strDst(strSrc);

会出现两个指针指向一个内存的问题,就会存在连续释放两次的危险

为了解决这种个问题,需要使用深拷贝

Cstring::Cstring(const Cstring & rhs)

{

m_pData = new char[strlen(rhs.m_pData)+1];

strcpy(m_pData,rhs.m_pData);

}

Cstring& Cstring::operator=(const Cstring &rhs)

{

if(this==&rhs)

return *this;

if(m_pData!=NULL)

delete m_pData;

m_pData = new char[strlen(rhs.m_pData)+1];

strcpy(m_pData,rhs.m_pData);

return *this;

}

代码例子

#define _CRT_SECURE_NO_WARNINGS

#include<iostream>

#include<cstring>

using namespace std;

class A

{

private:

int a[4];

public:

A() :a{ 1,2,3,4 }

{

for (int i = 0; i < 4; i++)

cout << a[i] << endl;

}

};

class Cstring

{

public:

Cstring(char *data,int a):m_pdata(data)

{

}

Cstring (char *data)

{

m_pdata =data;

}

Cstring(const Cstring & rhs);

Cstring & operator=(const Cstring &rhs);

void play()

{

cout << m_pdata << endl;

}

private:

char *m_pdata;

int m_nsize;

};

Cstring::Cstring(const Cstring & rhs)

{

m_pdata = new char[strlen(rhs.m_pdata) + 1];

strcpy(m_pdata, rhs.m_pdata);

}

Cstring& Cstring::operator=(const Cstring &rhs)

{

if (this == &rhs)

return *this;

if (m_pdata != NULL)

delete m_pdata;

m_pdata = new char[strlen(rhs.m_pdata) + 1];

strcpy(m_pdata, rhs.m_pdata);

return *this;

}

int main()

{

A m;

Cstring strSrc("Hello everyone!");

Cstring strDst(strSrc);

strDst.play();

cout<<"hello world!"<<endl;

return 0;

}

28 拷贝构造函数的深拷贝与浅拷贝的问题

深拷贝是当一个对象需要复制另外一个对象时,这个对象的指针不能直接指向这个对象,而是需要分配内存

标准的构造函数的写法

A::A(const A & m)

{

m_data = new 私有指针对象

strcpy(m_data,m.data);

m_int = m_i;

…….

}

A & A::operator=(const A & m) //重载=运算符

{

if(this==m) return *this;

if(m_data!=NULL)

delete m_data;

m_data = m.data;

strcpy(m_data,m.data);

return *this;

}

补充1 异常处理

try catch机制

如果catch中函数满足条件,就执行try中的函数 ,

补充2

C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生,声明为explicit的构造函数不能在隐式转换中使用。

来自 <https://blog.csdn.net/qq_35524916/article/details/58178072>

谨防构造函数抛出异常而引发问题

当在构造一个对象时,如果存在动态内存分配的情况,如果分配不成功,对象就没有创建成功,这时候是不能调用析构函数的,所以就存在内存泄漏

解决问题的方法就是使用异常处理

下表是对上面层次结构中出现的每个异常的说明:

异常

描述

std::exception

该异常是所有标准 C++ 异常的父类。

std::bad_alloc

该异常可以通过 new 抛出。

std::bad_cast

该异常可以通过 dynamic_cast 抛出。

std::bad_exception

这在处理 C++ 程序中无法预期的异常时非常有用。

std::bad_typeid

该异常可以通过 typeid 抛出。

std::logic_error

理论上可以通过读取代码来检测到的异常。

std::domain_error

当使用了一个无效的数学域时,会抛出该异常。

std::invalid_argument

当使用了无效的参数时,会抛出该异常。

std::length_error

当创建了太长的 std::string 时,会抛出该异常。

std::out_of_range

该异常可以通过方法抛出,例如 std::vector 和 std::bitset<>::operator[]()。

std::runtime_error

理论上不可以通过读取代码来检测到的异常。

std::overflow_error

当发生数学上溢时,会抛出该异常。

std::range_error

当尝试存储超出范围的值时,会抛出该异常。

std::underflow_error

当发生数学下溢时,会抛出该异常。

来自 <http://www.runoob.com/cplusplus/cpp-exceptions-handling.html>

29 多态基类的析构函数应该为虚

当一个派生类对象使用一个基类对象删除,对象没有虚析构函数时,将不会调用析构链

在使用虚析构函数时:

1、类中至少包含一个虚函数

不要去继承没有虚析构函数的类

多态基类的析构函数应该是virtual的,也必须是virtual的,这样才能保证派生类的对象彻底释放

补充:多态存在的条件

1、 要有继承

2、有虚函数的重写

3、父类指针或者引用指向子类只针对或者引用

30 绝对不能让构造函数为虚函数

虚函数的多态机制是使用一个虚函数表

这个表中存放着虚函数的地址

构造函数返回之前,虚函数表还没有建立,因此不允许构造函数为虚

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: