开发成长之路(6)-- C++从入门到开发(C++入门不难)

举报
看,未来 发表于 2021/04/29 03:24:05 2021/04/29
【摘要】 文章目录 C++背景介绍:C++入门真的不难C++语言与C语言的异同类类方法C++ 类访问修饰符类继承构造/析构函数拷贝构造函数this指针 C++ 动态内存数组的动态内存分配对象的动态内存分配 这个图有点偏差啊,C++是要排在QT之前的,回头我会对这个图进行一波的微调。 这已经是进入了第二个阶段了,此前如果C语言基础还没有打好的小伙伴可以...

在这里插入图片描述

这个图有点偏差啊,C++是要排在QT之前的,回头我会对这个图进行一波的微调。

这已经是进入了第二个阶段了,此前如果C语言基础还没有打好的小伙伴可以再补一下C语言:
开发成长之路(1)-- C语言从入门到开发(入门篇一)
开发成长之路(2)-- C语言从入门到开发(函数与定制输入输出控制函数)
开发成长之路(3)-- C语言从入门到开发(讲明白指针和引用,链表很难吗?)
开发成长之路(4)-- C语言从入门到开发(距离开发,还差这一篇)
开发成长之路(5)-- C语言从入门到开发(仿ATM机项目,我写的第一个项目)


C++背景介绍:C++入门真的不难

C++和C经常被放在一起写,这难道还需要我再解释什么吗?
C/C++。

C++,在C语言的基础上增添了新的特性,主要为类。
其实类也是源自于对C语言结构体的发扬光大。正因为有了类的出现,C++带有着强的封装性、继承性、多态性。
而后其它的一切,都是由于这些特性而做的二次开发,从而在发展的道路上一骑绝尘。

大家觉得C++难,也就是难在这些后继发展的内容上吧。
这个阶段,让我们忘掉那些,探求最简单的C++基本语法!!!


C++语言与C语言的异同

技术点 异/同
环境搭建
编码规范 略异
基本数据类型
标准输入输出
运算符
字符串 略异
分支循环
函数
类/结构体
指针/引用
分文件编程
调试

1、编码规范
在C++中引用的头文件和C中的头文件不太一样,但是这并不妨碍二者互用,兼容的。
C里面的输入输出头为:

include<iostream>

using namespace std;	//这一行意为使用名空间std,std里面包含了很多东西

  
 
  • 1
  • 2
  • 3

2、标准输入与输出
在C++里面,输入输出没那么的麻烦,

cin>>输入内容>>代码>>继续输入;
cout<<输出内容<<代码<<继续输出;

  
 
  • 1
  • 2

3、字符串。
C++中有专门的字符串类。

#include <string>
using namespace std;

  
 
  • 1
  • 2

支持的方法有:

函数 目的
strcpy(s1, s2); 复制字符串 s2 到字符串 s1。
strcat(s1, s2); 连接字符串 s2 到字符串 s1 的末尾。连接字符串也可以用 + 号
strlen(s1); 返回字符串 s1 的长度。
strcmp(s1, s2); 如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回值小于 0;如果 s1>s2 则返回值大于 0。
strchr(s1, ch); 返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
strstr(s1, s2); 返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

4、类,后面细讲


整张图来看的明白(源自菜鸟编程):
在这里插入图片描述

其他的不必讲了吧,讲一下那个变量和方法、访问修饰符。

类方法

变量,称为类的属性。函数,称为类的方法。

我们来一个实际的例子看一下:

class Box
{ public: double length; // 长度 double breadth; // 宽度 double height; // 高度 double getVolume(void) { return length * breadth * height; }
};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

也可以在类的外部使用范围解析运算符 :: 定义该函数

double Box::getVolume(void)
{ return length * breadth * height;
}

  
 
  • 1
  • 2
  • 3
  • 4

值得注意的是,在分文件写代码的时候,需要将类及类方法声明在.h文件中,而类方法的实现放在.cpp文件中,这时候就需要下面的写法了。

初始化类对象,并调用成员函数的方法:

Box myBox; // 创建一个对象
 
myBox.getVolume();  // 调用该对象的成员函数

  
 
  • 1
  • 2
  • 3

或:

Box *myBox = new Box(); // 创建一个对象
 
myBox0->getVolume();  // 调用该对象的成员函数

  
 
  • 1
  • 2
  • 3

C++ 类访问修饰符

类成员的访问限制是通过在类主体内部对各个区域标记 public、private、protected 来指定的。

为什么说C++有很强的封装性呢,就是因为这三个类访问修饰符。
且看下去:


class Base { public:
  // 公有成员,可以在类外被随意访问 protected:
  // 受保护成员,受保护继承的子类可以使用,自己和友元也可以使用 private:
  // 私有成员,只能在本类内使用,友元函数也行
 
};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

我们一般将某些必须开放的接口设置为公有,有些看情况设置为保护,其余一律设为私有。
类的属性不建议公有!!!

示例:

class Box
{ public: void setWidth( double wid ); double getWidth( void ); private: double length; double width;
};
 
// 成员函数定义
double Box::getWidth(void)
{ return width ;	
}
 
void Box::setWidth( double wid )
{ width = wid;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

类继承

有public, protected, private三种继承方式,它们相应地改变了基类成员的访问属性。

继承方法 基类 public 成员,protected 成员,private 成员的访问属性在派生类中分别变成:
public 继承 public, protected, private
protected 继承 protected, protected, private
private 继承 private, private, private

可以看出,private 成员只能被本类成员(类内)和友元访问,不能被派生类访问;protected 成员可以被派生类访问。

示例:

class A{
public:
  int a;
  A(){ a1 = 1; a2 = 2; a3 = 3;
  }
  void fun(){ cout << a1 << endl;   //正确 cout << a2 << endl;   //正确 cout << a3 << endl;   //正确
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};

class B : public A{
public:
  int a;
  B(int i){ A(); a = i;
  }
  void fun(){ cout << a << endl; //正确,public成员 cout << a1 << endl; //正确,基类的public成员,在派生类中仍是public成员。 cout << a2 << endl; //正确,基类的protected成员,在派生类中仍是protected可以被派生类访问。 cout << a3 << endl; //错误,基类的private成员不能被派生类访问。
  }
};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

构造/析构函数

在初始化类的对象的时候会需要用到类的构造函数,构造函数的名称与类的名称是完全相同的,并且不会返回任何类型、

构造函数可用于为某些成员变量设置初始值。

来看个例子:

class Line
{ public: Line();  // 这是构造函数
};
 
// 成员函数定义,包括构造函数
Line::Line(void)
{ cout << "Object is being created" << endl;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数。

像这样:

class Line
{ public: Line(double len);  // 这是构造函数 private: double length;
};
 
// 成员函数定义,包括构造函数
Line::Line( double len)
{ cout << "Object is being created, length = " << len << endl; length = len;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

还可以这样:

Line::Line( double len): length(len)
{ cout << "Object is being created, length = " << len << endl;
}

  
 
  • 1
  • 2
  • 3
  • 4

看个人喜好了。


析构函数呢,相对比较简单,但是也是有坑在里面的。

类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。
一般用于程序员手动回收内存。

class Line
{ public: Line();   // 这是构造函数声明 ~Line();  // 这是析构函数声明
};
 
// 成员函数定义,包括构造函数
Line::Line(void)
{ cout << "Object is being created" << endl;
}
Line::~Line(void)
{ cout << "Object is being deleted" << endl;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。

class Line
{ public: Line( int len ); // 简单的构造函数 Line( const Line &obj); // 拷贝构造函数 ~Line(); // 析构函数 private: int *ptr;
};
 
// 成员函数定义,包括构造函数
Line::Line(int len)
{ cout << "调用构造函数" << endl; // 为指针分配内存 ptr = new int; *ptr = len;
}
 
Line::Line(const Line &obj)
{ cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl; ptr = new int; *ptr = *obj.ptr; // 拷贝值
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

this指针

this指针存在于类中,指代的是这个类本身的意思。
其实我也想不出来太多它必须存在的场景,碧如说:参数名和类属性名一样的时候,或者函数指针参数名和类方法名一样的时候吧。

反正看到this的时候不要大惊小怪就好啦。


关于类,大致讲到这里。


C++ 动态内存

了解一下堆栈:

 栈:在函数内部声明的所有变量都将占用栈内存。 堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。

  
 
  • 1
  • 2

使用 new 运算符来为任意的数据类型动态分配内存的通用语法:

new data-type;

  
 
  • 1

使用 delete 操作符释放它所占用的内存:

delete pvalue; // 释放 pvalue 所指向的内存

  
 
  • 1

示例:

double* pvalue  = NULL; // 初始化为 null 的指针
pvalue  = new double;   // 为变量请求内存

balabala

delete pvalue; // 释放 pvalue 所指向的内存

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

数组的动态内存分配

直接上手吧:

char* pvalue  = NULL;   // 初始化为 null 的指针
pvalue  = new char[20]; // 为变量请求内存

delete [] pvalue; // 删除 pvalue 所指向的数组

  
 
  • 1
  • 2
  • 3
  • 4

对象的动态内存分配

int main( )
{ Box* myBoxArray = new Box(); delete myBoxArray; return 0;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

先到这里啦,我还有点事情。

在这里插入图片描述

文章来源: lion-wu.blog.csdn.net,作者:看,未来,版权归原作者所有,如需转载,请联系作者。

原文链接:lion-wu.blog.csdn.net/article/details/116236588

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。