C++基础第一部分

C++基础

c++概述

C++是对c的扩展,是c语言的超集。


库是编程模块的集合,可以在程序中调用它们,库对很多常见的编程问题提供了可靠的解决方法,因此可以节约大量的时间和工作量。
c++ 在c语言基础上增加了面向对象和泛型编程的思想。
::双冒号 作为全局作用域

命名空间

namespace命名空间的主要用途, 用来解决命名冲突的问题
1.命名空间下, 可以放 函数, 变量, 结构体, 类
2.命名空间必须定义在全局作用域下
3.命名空间可以嵌套命名空间
4.命名空间是开放的,可以随时向命名空间添加内容,合并并不是覆盖
5.匿名命名空间,namespace,  static int m_c; 只能在当前文件使用
6.命名空间可以起别名 namespace xx= VV;

using namespace

using 声明, 注意避免二义性问题
写了using 声明以后,下面这行代码表示看到的sunwu都是KIngGlory下面的
但是 编译器有就近原则
所以会导致二义性
//using编译指令
using namespace KingGlory;//打开房间
 KingGlory::sunwu; 指定哪个房间

C++对c的增强

  1. 全局变量检测增强
  2. 函数检测增强,参数检测增加,返回值检测增强,函数调用增强
//int getRectS(w, h)
//{
//
//}
  1. 类型转换检测增强
  2. struct 增强
struct Person
{
	int age;
	void plusAge() {age++}; //c语言中不可以加函数
};
  1. bool 类型增强, c语言中没有bool类型
  2. 三目运算符增强
    a>b?a:b
  3. const增强, c语言可以通过地址来修改值,全局区受到了保护不可以更改,这里的变量时伪常量。
  4. const c语言中默认是 外部链接 ,c++默认是内部链接, 外部,只要其他文件有就可以找到
  5. const int b = 20; int *p = (int *)&b; 取地址的话会分配临时内存 ,加上extern 也会分配
  6. 用变量初始化,也会分配内存,凡是分配内存的, 都可以更改值
  7. 自定义数据类型,
  8. 尽量用const 替换define

3. 引用(重点)

3.1 引用的基本用法

引用是C++对c的重要扩充

  • 变量名实质上是一段连续内存空间的别名, 是一个标号(门牌号)
  • 程序中通过变量名来申请并且命名内存空间
  • 通过变量名的名字可以使用存储空间
3.1.1 引用基本语法 Type &别名 = 原名

void test01() {
int a = 10;
int &b = a;
b = 12;
cout << “a=” << a << " b = " << b << endl;
}

3.1.2. 引用必须初始化

void test2() {
int a = 10;
int &b = a;//数组必须初始化
int c = 20;
b = c; //赋值
}

3.1.3.对数组进行引用

void test3()
{
int arr[10];
for (int i = 0; i < 10; i++)
{
arr[i] = i;
}
//给数组起别名
int(&pArr)[10] = arr;
for (int i = 0; i < 10; i++) {
cout << pArr[i] << " ";
}
cout << endl;
//第二种方式
typedef int(ARRAYREF)[10]; //一个具有10个元素的类型数组
ARRAYREF &pArr2 = arr;
for (int i = 0; i < 10; i++) {
cout << pArr2[i] << " ";
}
cout << endl;
}

3.2 参数的传递方式

注意事项

  • &在此不是求地址运算,而是起标识作用
  • 类型标识符是指目标变量的类型
  • 必须在声明引用变量时进行初始化
  • 引用初始化之后不能改变
  • 不能有NULL引用,必须确保引用是和一块合法的存储单位关联
  • 可以建立对数组的引用

3.3 引用的本质

引用的本质在C++ 内部实现是一个指针常量

3.4 指针的引用

用一级指针引用,可以代替二级指针
常量引用, 修饰形参为只读
const int &a = 10;会分配内存

封装,继承,多态

类和对象 关系??
  1. 类是对象的抽象
  2. 对象是类的实例
内联函数 解决宏缺陷问题

函数声明加了关键字, 函数实现也要加关键字inline

函数重载的基本语法

  • 函数名称相同, 在同一个作用域下
  • 函数参数个数不同,类型不同,顺序不同
  • 函数 的返回值不可以作为函数重载条件
  • 函数重载碰到了函数默认参数,注意避免二义性

extern C 浅析

解决了C++语言中调用c语言的代码
ifdef __cplusplus extern “C”{}

C语言下的封装和c++的封装

c语言属性和行为分开,类型检测不够
将属性和行为作为一个整体, 来表示生活中具体的事物
有访问权限
class 和struct唯一区别默认权限不同
class默认是private, struct 默认是public
public 类内类外都可以访问
protected 类内可以,类外不可以
private, 类内可以,类外不可以

对象的析构和构造

初始化和清理

构造函数---->用来初始化的
构造函数没有返回值,没有void, 可以发生重载
析构函数---->用来清理的 对象清理
没有返回,没有void, ~ 不可以发生重载
系统会自动调用构造函数和析构函数, 而且只会调用一次

构造函数的分类及调用

按照参数类型

无参构造(默认构造) 有参构造

按照类型分类

普通构造函数 拷贝构造函数

无参构造写法和调用

Person p1 Person(p1)
构造函数调用方式
括号法调用
默认构造函数不要加()
如果是匿名对象, 如果编译器发现了对象是匿名的,那么在这个代码结束后,就释放这个对象
不能用拷贝对象初始化匿名对象
Person p = 100;隐式类型转换 person p = Person(100)

拷贝构造函数调用实际

  1. 用已经创建好的对象来初始化新的对象
  2. 以值传递的方式给函数参数赋值
  3. 以值传递方式返回局部对象
  4. release 默认会做优化

构造函数的调用规则

//系统默认提供三个函数, 默认构造, 拷贝构造, 析构函数
//当我们提供有参构造函数, 系统不提供默认构造函数
//系统还会默认的拷贝构造函数

深拷贝和浅拷贝

浅拷贝

同一类型的对象之间可以相互赋值, 使得两个对象的成员变量的值相同, 但两个对象是独立的,这种情况是浅拷贝。
一般情况下,浅拷贝没有任何副作用,但当类中有指针,并且指针指向动态分配的内存空间,析构函数做了动态内存释放的处理,会导致内存问题。
系统默认提供的拷贝构造,会进行简单的值拷贝
如果属性里有指向堆区空间的数据,那么简单的浅拷贝会导致重复释放内存的异常
解决上述问题,需要我们自己提供构造数据,进行深拷贝

初始化列表的基本使用

在构造函数的后面+ : 属性(值。参数)

类对象作为成员的案例

类对象作为类成员的时候,构造顺序现将类对象一一构造, 然后构造自己析构的顺序是相反的。
析构顺序与构造相反

explicit

explicit 关键字,防止构造函数中的隐式类型转换

动态对象创建

void test01()
{
	//栈区开辟
	Person p1;
	Person * p2 = new Person;//堆区开辟
	//所有new出来的对象,都会返回该类型的指针 
	//new 会调用构造
	//new 运算符, malloc 函数
	delete p2;
	//malloc 对应free new 对应delete
	//用void *接受对象,无法释放

}

如果在new表达式中使用[],必须在相应的delete表达式中也使用[],如果在new表达式中不适用[], 在delete也不要使用

静态成员变量

在一个类中, 将一个成员变量声明为static, 这种成员称为静态成员变量,无论简历多少个对象都只有一个静态数据的拷贝。静态成员变量属于某个类, 所有对象共享。

静态变量,在编译的时候就分配空间, 对象还没创建的是很好,就已经分配空间。

  • 静态成员变量必须在类中声明, 在类外定义
  • 静态数据成员不属于某个对象, 在为对象分配空间中国,不包括静态成员所占的空间
  • 静态数据成员可以通过类名或者对象名来引用。
静态成员实现单例模式

单例模式——xizhu

  • 目的 为了让类中只有一个实例,实例不需要自己释放
  • 将默认构造和拷贝构造 私有化
  • 内部维护一个指针
  • 私有化唯一指针
  • 对外提供getInstance方法来访问这个指针
  • 保证类中只能实例化一个对象
    单例模式–打印机案例
    类似xizhu案例
    提供打印机接口

4.C++面向对象模型初探

成员变量和函数的存储

C++ 中的“数据” 和处理数据的操作(函数) 是分来存储的

  • C++中的非静态尘缘函数直接内含在类对象中,就像c strcut 一样
  • 成员函数 虽然内含在class声明之类,却不出现在对象中
  • 每一个非内联成员函数只会诞生一个实例

this指针

this指针指向被调用的成员函数所属的对象
编译器会偷偷加入一个this指针
Tips:静态成员内部没有this指针, 静态成员函数不能操作非静态成员变量

  • 指针永远指向当前对象
  • 解决命名冲突问题
  • *this

空指针访问成员函数

如果成员函数没有用到this, 那么空指针可以直接访问成员函数
如果成员函数用到看,就要注意,加判断

常函数 常对象

常函数, void func() const{} 常函数
常函数 修饰的是this指针, const Type * const this
常函数 不能修改this指针执行的值

常对象 在对象前加入 const修饰 const Person p1
常对象不可以调用普通的成员函数, 因为普通的成员函数可以修改其内部成员值
用mutable修饰的关键字在常函数可以修改的

5. 友元函数

让全局的好基友函数作为有缘 全局函数写到类中并且声明
friend void gooGay(Buiding * building);
全局函数 好基友
有元函数 目的访问类中私有成员属性
让整个类做友元类
友元类 是单向的不可传递

6. 强化训练(数组封装类)

#pragma once
#include "stdafx.h"
#include
using namespace std;

class MyArray {
public:
	MyArray(); //默认构造,容量100
	MyArray(int capacity);
	MyArray(const MyArray & array);

	~MyArray();
	//尾插法
	void push_back(int val);
	//根据索引获取值
	int geyData(int index);
	//根据索引设置值
	void setData(int index,int val);
	int getSize();
	int getCapacity();

private:
	int * pAddress; //指向真正存储数据的指针
	int m_Size;//数组大小
	int m_Capacity; //数组容量
};

// 强化数组封装.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "MyArray.h"

void test01()
{
	//堆区创建数组
	MyArray * array = new MyArray(30); 
	delete array;
}
int main()
{
	test01();
	system("pause");
    return 0;
}

你可能感兴趣的:(c++,c++)