类
类的构造:
#ifndef DEMO_STUDENT_H
#define DEMO_STUDENT_H
class Student {
//如果外界想访问private的变量,但是没有get/set方法,则可以用友元函数
friend void test(Student*);
//友元类,里面可以访问student的所有私有变量
friend class Teacher;
int age;
public:
Student(int age);
Student();
~Student();
void setAge(int age);
//常量函数,不能去修改类里面的成员变量值,只能读取。保护成员变量。
void printAge(int age) const;
private:
int score;
protected:
char *name;
};
#endif //DEMO_STUDENT_H
友元函数去访问私有变量
//友元函数
void test(Student *student) {
student->score = 10;
}
int main() {
Student student;
cout << "hello world"<<endl;
Student student1(10);
test(&student);
}
单例模式
Person.h
class Person {
private:
static Person* instance;
Person();
public:
static Person* getInstance();
};
Person.cpp
#include "Person.h"
Person* Person::instance = 0;
Person *Person::getInstance() {
if(!instance){
instance = new Person();
}
return instance;
}
操作符重载
头文件
Student operator+(Student &student);
cpp文件
Student Student::operator+(Student &t) {
Student student;
student.score = this->score + t.score;
return student;
}
使用操作符重载:
Student student;
Student student1(10);
Student student2 = student + student1;
printf("%d",student2.score);
继承
C++继承用冒号:后面加上父类表示继承。
前面可以加上public/private表示可以继承父类的public或private方面。不写默认是private的。
class Child : public Person {
Child(){
//子类中调用父类方法
Person::test();
}
};
多态
//静态多态
Person *child = new Child();
//此时调用的是父类的方法
child->test();
//动态多态
//利用虚函数,将父类方法设定为虚函数,则会调用子类方法
//virtualTest()方法是父类里的virtual方法
child->virtualTest();
析构方法声明为虚函数,这样子类才能释放。
//纯虚函数,相当于java里的abstract,子类里必须实现
virtual void test1()=0;
泛型基础:模板编程
//泛型基础:模板编程
//函数模板,相当于java里的泛型方法
//类模板,相当于java里的泛型类
//函数模板,在函数前声明template
template <typename T>
T test(T i,T j){
return i>j?i:j;
}
//类模板
template <class T,class E>
class TClass{
public:
T test(T t){
return t;
}
E test2(E e){
return e;
}
};
int main(){
TClass<int,float> t;
t.test(1);
t.test2(1.0);
}
类型转换
C语言的强转和java类似,
TYPE b = (TYPE)a;
C++强转
1、const_cast
2、static_cast
3、dynamic_cast
4、reinterpret_cast
TYPE b = static_cast(TYPE)a;
//const_cast
//强转类型为const或volatile属性
const char* a;
char *b = const_cast<char*>(a);
//static_cast
//1、基础类型之间互转,如:float转int,int转unsigned int
//2、指针与void之间互转,如:float* 转 void*,Bean* 转 void*,指针函数转 void*等
//3、子类指针/引用与父类指针/引用转换
Person *p = new Person();
Child *c = static_cast<Child*>(p);
c->test();
//dynamic_cast
//主要将基类指针、引用,安全的转为派生类
//在运行时对可疑的转型操作进行安全检查,仅对多态有效
//基类至少有一个虚函数
//对指针转换失败的得到NULL,对引用失败,抛出bad_cast异常
Child* cc = dynamic_cast<Child*>(p);
if(!cc){
cout<<"转换失败"<<endl;
}
异常
void test(){
throw "异常";
}
void test2(){
throw exception();
}
捕获异常
try {
test();
}catch (exception &e){
cout<<e.what()<<endl;
}
try{
test2();
}catch(const char *m){
cout<<m<<endl;
}
文件与流操作
C文件读写
C文件读写
FILE *f = fopen("xxx.txt","w");
fputc('a',f);
fclose(f);
f = fopen("xxx.txt","w");
fputs("123",f);
fclose(f);
//读取字符
fgetc(f);
char buf[255];
FILE *ff = fopen("xxx.txt","r");
//读取输入字符,直到空格停止
fscanf(ff,"%s",buf);
//读取字符
fgets(buf,255,ff);
fclose(ff);
//二进制IO函数
//参数:
// 1、写入、读取的数据缓冲区
// 2、每个数据大小
// 3、多少个数据项
// 4、流
size_t fwrite(const void * __ptr, size_t __size, size_t __nitems, FILE * __stream)
size_t fread(void * __ptr, size_t __size, size_t __nitems, FILE * __stream)
fwrite(buf,1024,1,ff)
C++形式的文件读写
//ofstream 输出文件流,创建文件并向文件写入信息
//ifstream 输入文件流,从文件读信息
//fstream 文件流,可读可写
char data[100];
//以写模式打开文件
ofstream outfile;
outfile.open("xxx.txt");
cin >> data;
//向文件中写入data
outfile<<data<<endl;
//关闭打开的文件
outfile.close();
//以读模式打开文件
ifstream infile;
infile.open("xxx.txt");
//读取文件
infile>>data;
//关闭文件
infile.close();
容器
序列式容器
//导入
#include <vector>
using namespace std;
//容器 : stl:标准模板库
//序列式容器和关联式容器
//序列式容器:元素排列顺序与元素本身无关,由添加顺序决定
//vector、list、 dequeue、 queue、 stack、 priority queue
//声明一个空容器
vector<int> vector1;
//声明一个有一个元素空间的容器
vector<int> vector2(1);
//6个元素,值都为1
vector<int> vector3(6,1);
//复制容器
vector<int> vector4(vector3);
//添加
vector1.push_back(10);
//取元素
int v = vector1[0];
//队前和队尾
int front = vector1.front();
int back = vector1.back();
vector1.clear();
vector1.erase(vector1.begin(),vector1.end());
关联式容器
//导入
#include <set>
using namespace std;
//关联式容器 set map
//set 集合 元素不可重复
set<int> set1 = {1, 2, 3, 4};
//添加重复元素,添加失败
set1.insert(1);
//根据添加的返回值,看是否添加成功
pair<set<int>::iterator, bool> pair = set1.insert(5);
int size = set1.size();
//迭代器,指向第一个元素
set<int>::iterator begin = set1.begin();
//指向最后一个元素的后面,不是最后一个元素
set<int>::iterator end = set1.end();
//遍历
for (; begin != end; begin++) {
int p = *begin;
}
map<int,string> map1;
map<int,string> map2 = {{1,"a"},{2,"b"}};
map2.insert({3,"c"});
map2[1] = "d";
命名空间
namespace space1{
void fun(){
}
}
namespace space2{
void fun(){
}
}
int main() {
space1::fun();
space2::fun();
}
引用和指针
1、不存在空引用,引用必须连接到一块合法的内存;
2、所有引用必须在创建时初始化,初始化后就不能再指向另一个对象;
3、指针可以在任何时候初始化,初始化后还可以指向其他对象。
int i = 10;
double d = 10.0;
int*p = &i;
int&r = i;
double&s = d;
//指针获取对象时,需要用*
int a = *p;
//引用获取对象时,直接用引用
int c = r;












网友评论