C++ 三大特性
封装
客观的事物封装成抽象的类(将数据和方法打包在一起,加权限的区分)
多态
简单概括为一个接口多种方法(面向未来编程)
继承
表达的是类与类之间的关系,使得对象可以继承另一对象的特征和能力。
目的: 减少代码冗余
作用域
#include <iostream>
using namespace std;
int a =10;
void test01(){
int a =20;
// 就近原则 优先选择局部变量
cout <<"局部变量:"<< a <<endl;
// 作用域 运算符
cout << "全局变量:"<<::a<<endl;
}
int main()
{
test01();
return 0;
}
命名空间
- 为了解决命名冲突
- 可以重复嵌套
- 可以声明实现分离
- 可在命名空间外部定义
- 通过using 引入
定义
namespace NameSpaceA {
int a =10;
void sayHello(){
std::cout<<"A: Hello World!"<<std::endl;
}
}
namespace NameSpaceB {
int a =20;
void sayHello(){
std::cout<<"B: Hello World!"<<std::endl;
}
}
// 嵌套的命名空间
namespace OuterSpace {
int a =10;
namespace InnerSpace {
int a =20;
}
}
// 命名空间是开放的 可以随时加入
// 引入重载
namespace NameSpaceA {
void sayHi(){
std::cout <<"Hi World!"<<std::endl;
}
void func(bool flag){std::cout<<flag<<std::endl;}
void func(int a){std::cout<<a<<std::endl;}
void func(int a,int b){std::cout<<a<<","<<b<<std::endl;}
}
// 声明实现分离
namespace TestSpace {
void hello();
void test();
}
// 命名空间外部定义
void TestSpace::test(){
std::cout <<"test"<<std::endl;
}
// 声明分离
namespace TestSpace {
void hello(){
std::cout <<"hello" <<std::endl;
}
}
// 命名空间别名
namespace VeryLongNameHHHHHHHH {
bool flag =false;
}
使用
可以使用 using 引入命名空间(引入后可直接使用)
没有引用的要加 作用域运算符 来指定
#include <iostream>
#include "nameSpace.hpp"
using namespace std;
using namespace NameSpaceB;
int main()
{
NameSpaceA::sayHello(); // 指定使用
sayHello(); // 引入后直接使用
cout <<"外部空间:"<<OuterSpace::a<<endl;
cout <<"内部空间:"<<OuterSpace::InnerSpace::a<<endl;
NameSpaceA::sayHi();
// 命名空间别名
namespace shortSpace = VeryLongNameHHHHHHHH;
cout.setf(ios::boolalpha);
cout <<shortSpace::flag<<endl;
// 引入部分
using NameSpaceA::func;
func(1);
func(1,2);
func(false);
return 0;
}
无名命名空间
namespace{
}
意味仅本文件内使用
结构体
struct Student{
string name;
int id;
};
C++ 中结构体 使用可以不加 struct
关键字
// struct Student s1 = {"jack",1}; // c-style
Student s1={"jack",1};
成员函数
struct Student{
private:
string name;
int id;
public:
string getName() const{
return this->name;
}
void setName(const string name){
this->name=name;
}
int getId()const{
return this->id;
}
void setId(const int id){
this->id=id;
}
Student(string name,int id):name(name),id(id){}
};
在C++中结构体内可以定义函数,和变量。
bool
C++ 中引入了布尔类型 bool
bool flag = true;
三目运算符
C语言三目运算符表达式返回值为数据值,为右值
,不能赋值.
int a =10;
int b =20;
printf("ret:%d\n",a>b?a:b);
C++三目运算符返回右值引用
,可以被赋值。
int a=10,b=20;
a>b?a:b = 100;
cout <<"a:"<<a<<endl
<<"b:"<<b<<endl;
const
C语言中 const
表示只读变量,默认是外部链接
(其他源文件可以使用)
func.c
const int num =100;
main.c
extern const int num;
printf("%d",num);
C++ const修饰的全局变量,默认是内链接
(只在当前文件使用)
c++ 中基础类型 不会开辟空间, 会放到符号表中
因此下面的修改是无效的
const int data =10;
int* const ptr = (int*)&data;
*ptr = 100;
cout <<"data:"<<data<<endl;
int _a = 10;
const int _b =_a; // 系统会开辟空间
int* const _ptr =(int*)&_b;
*_ptr =100;
cout <<"_a:"<<_a<<endl;
cout <<"_b:"<<_b<<endl;
但是当我们把代码修改成这样,会发现值被修改了。
因为当我们创建变量_b
时系统并没有将其放入到符号表中。
尽量使用
const
替换define
引用
已知变量的
别名
int a =10;
int& r1 = a; // 这里并不是取地址 r1 是 a 的引用(别名)
// int* p =&a; // 取地址
能用引用,不用指针!
// 引用
int num =1;
int& r1 =num;
cout <<"num:"<<&num<<endl;
cout <<"r1:"<<&r1<<endl;
num:0x61fe48
r1:0x61fe48
地址是相同的!
- 引用必须初始化
- 引用一旦初始化就不能再次修改
别名
引用数组
// 引用数组
int arr[5]={0,1,2,3,4};
// 注意 加()区分 全部引用 和 局部引用
int(& r2)[5] = arr;
r2[0]=1;
vector<int> vc(arr,arr+5);
for_each(vc.begin(),vc.end(),[&](int t){
cout <<t<<
" ";
});
1 1 2 3 4
当然为了解决上面问题我们也可用typedef
// typedef 类型起别名
typedef int TYPE_ARR[5];
TYPE_ARR& rArr =arr;
cout <<rArr[0]<<endl;