C++概述

C++概述

C++语言在C语言的基础上添加了面向对象编程泛型编程的支持。

面向对象的3大特征

封装、继承、多态

命名空间

//命名空间
// A是空间的名字
namespace A{
	int a;
	void func()
	{

	}
}
  1. 命名空间的注意
    • 注意1:命名空间只能写在全局
    • 注意2:命名空间可以嵌套命名空间
    • 注意3:命名空间是开发的,随时可以加入新成员,但是新成员只能在加入后使用
    • 注意4:匿名命名空间
    • 注意5:命名空间可以取别名
    • 注意6:分文件编写代码时,如果.h中有两个命名空间,但是里面的成员函数或成员变量同名时,在.cpp中实现函数时,需要加上命名空间。
//命名空间可以嵌套命名空间
namespace Maker
{
	int a;
	namespace B
	{
		int b;
	}
}
// 命名空间是开发的,随时可以加入新成员,但是新成员只能在加入后使用
namespace Maker
{
	int a;
	namespace B
	{
		int b;
	}
}
namespace Maker
{
	int c;
}

// 匿名命名空间
//类似于static int d=50;
namespace
{
	int d = 50;
}

// 命名空间可以取别名
void test01()
{
	//			新名字    旧名字
	namespace nameMaker = Maker;
	cout << nameMaker::a << endl;
}
  1. 分文件编写代码时,如果.h中有两个命名空间,但是里面的成员函数或成员变量同名时,在.cpp中实现函数时,需要加上命名空间。
test.h文件
#pragma once
#include <iostream>
using namespace std;

namespace myMaker1
{
	void func();
}

namespace myMaker2
{
	void func();
}

test.cpp文件
#include "test.h"
// 需要在函数名前面加入确定命名空间名字
void myMaker1::func()
{
	cout << "func" << endl;
}

作用域运算符

用来访问某个作用域里面的成员。

using声明和编译指令

using声明是让命名空间中某个标识符可以直接使用

namespace A
{
	int a = 10;
	int b = 20;
	int c = 30;
}

void test01()
{
	//using声明是让命名空间中某个标识符可以直接使用
	using A::a;
	cout <<a << endl;
	//int a = 50;//注意:using声明了某个变量,在该作用域内不能定义同名的变量
}

using编译指令,让某个命名空间中的标识符都可以直接使用

namespace A
{
	int a = 10;
	int b = 20;
	int c = 30;
}
void test02()
{
	// using编译指令,让某个命名空间中的标识符都可以直接使用
	using namespace A;
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;

	int a = 100;//为什么不会冲突
	// 类似于命名空中的a是全局变量,这里的a的局部变量
	cout << "a=" << a << endl;

}

struct类型加强

  • 加强1:定义变量时不需要使用struct
  • 加强2:结构体内可以写函数
//1. 结构体中即可以定义成员变量,也可以定义成员函数
struct Student{
	string mName;
	int mAge;
	void setName(string name){ mName = name; }
	void setAge(int age){ mAge = age; }
	void showStudent(){
		cout << "Name:" << mName << " Age:" << mAge << endl;
	}
};

//2. c++中定义结构体变量不需要加struct关键字
void test01(){
	Student student;
	student.setName("John");
	student.setAge(20);
	student.showStudent();
}

更严格的类型转换

不能隐性的转换,必须显示的转换

C语言代码如下:

#include <stdio.h>

int main(void)
{
	// 这句话在C语言中编译不会出错,但是在C++中编译会出错
	char* p = malloc(64);
	return 0;
}

同样的代码在C++中必须如下写:

#include <iostream>

int main(void)
{
	char* p =(char*) malloc(64);
	return 0;
}

三目运算法符

* c语言的三目运算符返回的是右值
* C++语言的三目运算符返回的是左值,是空间
* 放在赋值操作符左边的是左值,放在右边的是右值

C语言的代码如下:

#include <stdio.h>

int main(void)
{
	int a = 10, b = 20;
	printf("b=%d\n", a > b ? a : b);
	// 这个表达式返回的是右值,是数值,是20
	//(a > b ? a : b) = 100; err 相当于是20=100报错
	*(a > b ? &a : &b) = 100;
	printf("b=%d\n", a > b ? a : b);
	return 0;
}

C++的代码可以直接赋值

#include <iostream>
using namespace std;
int main()
{
	int a = 10, b = 20;
	cout << "a=" << a << endl;
	// 在C++中三目运算符返回的是左值,是空间
	(a > b ? a : b)=100;
	cout << "b=" << b << endl;
	return 0;
}

C/C++中的const

  1. C语言中const修饰的变量都有空间
  2. C语言的const修饰的全局变量具有外部链接属性
  3. C++语言的const的变量有时有空间,有时没有空间(发生常量折叠,且没有对变量进行取址操作)

C语言的代码如下:

#include <stdio.h>
// 常量区,一旦初始化不能修改
const int a = 10; 
void test()
{
	// a = 200;全局的const不能直接修改
	// int* p = (int*)&a;
	//*p = 20; 全局的const不能间接修改
	// printf("%d\n", a);
}
int main(void)
{
	const int b = 20; //栈区
	// b = 200; 局部的const修饰的变量不能直接修改
	int* p = (int*)&b;
	// 可以间接修改
	*p = 200; 
	printf("b=%d\n", b);
	return 0;
}

C++的代码如下:

#include <iostream>
using namespace std;
const int aa = 10;//没有内存
void test()
{
	//发生了常量折叠
	cout << "aa=" << aa << endl;//在编译阶段,编译器:cout<<"aa="<<10<<endl;

	//禁止优化volatile
	volatile const int bb = 20;//栈区
	// const int bb = 20;
	int* p = (int*)&bb;//进行了取址操作,所以有空间
	*p = 200;
	cout << "bb=" << bb << endl;//cout << "bb=" << 20 << endl;
	cout << "*p=" << *p << endl;

	cout << "a的地址=" << (int)&bb << endl;
	cout << "p指向的地址=" << (int)p << endl;


}

int main(void)
{
	test();
	return 0;
}
  1. C++语言中const修饰的全局变量具有内部链接属性

  2. extern const int c = 300;//加上extern就变为外部链接属性

  3. C++编译器不能优化的情况

    • 不能优化自定义数据类型
    • 如果用变量给const修饰局部变量赋值,那么不会被优化
    • 编译器是在编译阶段来优化数据的
  4. 尽量用const替代define

7.1 define没有数据类型,const修饰的变量有数据类型,可以进行数据类型检查

#define MA 128
const short ma = 128;
void func(short a)
{
	cout << "func(short a)" << endl;
}

void func(int a)
{
	cout << "func(int a)" << endl;
}
int main()
{
	func(ma);
	system("pause");
	return EXIT_SUCCESS;
}

7.2 const修饰的变量有作用域,define不重视作用域,不能限定常量的使用范围

#include <iostream>
using namespace std;

void test01()
{
	int a = 10;
	const int b = a; // 如果变量给const修饰的局部变量赋值,那么编译器不能优化
	int *p = (int*)&a;
	*p = 100;
	cout << "b = " << b << endl;
	cout << "*p = " << *p << endl;
}

// 自定义数据类型,编译器不能优化
struct Test
{
	Test() // 构造函数
	{
		a = 20;
	}
	int a;
};

void test02()
{
	// 数据类型定义变量
	// 类实例化对象
	const Test te;
	cout << "te.a修改前:" << te.a << endl;
	Test* p = (Test*)&te;
	p->a = 200;
	cout << "te.a修改后:" <<  te.a << endl; //没有优化,因为不能优化自定义数据类型
}

int main(void)
{
	test01();
	test02();
	return 0;
}

引用

  1. 引用是做什么:和C语言的指针一样的功能,并且使语法更加简洁
  2. 引用是什么:引用是给空间取别名
  3. 引用的语法
#include <iostream>
using namespace std;

void test01() {

	int a = 10;
	//给变量a取一个别名b
	int& b = a;
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "------------" << endl;
	//操作b就相当于操作a本身
	b = 100;
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "------------" << endl;
	//一个变量可以有n个别名
	int& c = a;
	c = 200;
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	cout << "c:" << c << endl;
	cout << "------------" << endl;
	//a,b,c的地址都是相同的
	cout << "a:" << &a << endl;
	cout << "b:" << &b << endl;
	cout << "c:" << &c << endl;
}
// 函数引用的使用
void func(int &a) // int &a = a;
{
	a = 300;
	cout << "----------" << endl;
}

int main(void)
{
	test01();
	int a = 150;
	func(a);
	cout << "a=" << a;
	return 0;
}
  1. 引用的注意事项
    注意1:int &b = a;这里&不是取地址操作符,是引用的标记作用
    注意2:引用创建时,必须初始化。//int &pRef;err
    注意3:引用一旦初始化不能改变它的指向
    注意4:引用必须引用一块合法的内存空间
  2. 数组的引用
#include <iostream>
using namespace std;

int main()
{
	int arr[] = { 1, 2, 3, 4, 5 };
	//第一种方法(常用)
	//1.定义数组类型
	typedef int(MY_ARR)[5];//数组类型
	//2.建立引用
	MY_ARR &arref = arr;//建立引用,int &b=a;

	//第二种方法(常用)
	//直接定义引用
	int(&arref2)[5] = arr;// int &b=a

	//第三种方法
	typedef int(&MY_ARR3)[5];//建立引用数组类型
	MY_ARR3 arref3 = arr;

	for (int i = 0; i < 5; i++)
	{
		cout << arref[i] << endl;
	}
	cout << endl;
	for (int i = 0; i < 5; i++)
	{
		arref2[i] = 100 + i;
		cout << arref2[i] << endl;
	}

	return 0;
}
  1. 引用的本质
    引用的本质是编译器在内部使用常指针来实现
#include <iostream>
using namespace std;

//发现是引用,转换为 int* const ref = &a;
void test(int& ref){
	ref = 100; // ref是引用,转换为*ref = 100
}
int main(){
	int a = 10;
	int& aRef = a; //自动转换为int* const aRef = &a;这也能说明引用为什么必须初始化
	aRef = 20; //内部发现aRef是引用,自动帮我们转换为: *aRef = 20;
	cout << "a:" << a << endl;
	cout << "aRef:" << aRef << endl;
	test(a);
	return 0;
}

指针的引用

  1. 指针的引用是给指针变量这块空间取别名
#include <iostream>
using namespace std;

void test01()
{
	char* p = "韩信";
	char* &p1 = p;
	cout << p1 << endl;
}

//被调函数
void func(char* &tmp)//char* &tmp=mp;
{
	char *p;
	p=(char*)malloc(64);
	memset(p, 0, 64);
	strcpy(p, "韩信");
	tmp = p;//省了*
}
//主调函数
void test02()
{
	char* mp = NULL;
	func(mp);//省了&
	cout << mp << endl;
}

int main()
{
	test02();
	return 0;
}

C和C++的区别(总结)

1.C语言的结构体不能写函数,C++可以

2.结构体定义变量时,C++不需要加struct关键字

3.更加严格的类型检查

4.const修饰的变量,C++有时没有内存,C语言的都有内存

5.三目运算符返回的值不一样

6.引用和C语言的指针功能一样
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值