C++基础知识

一、基础

  1. #define 用在头部,表示一个常量。

const:将一个的变量转变为常量,不可修改。

const的用途

  • 定义只读变量即常量

  • 修饰函数的参数和函数的返回值

  • 修饰函数的定义体,被const修饰表示不修改成员变量的值

  1. 变量名:1、不能是关键字。

  1. 只能是字母,数字,下划线。

  1. 只能是字母和下划线打头,数字不行。

  1. short 2B int 4B long 4B longlong 8B

  1. float 4B(要加f) double 8B

  1. 转义字符:\n 换行 == endl

\t 补齐8个位置 (水平制表) 补齐一个tab位

\\ == \

  1. continue:执行到本行,就不再继续往下执行,会直接执行下次循环。

  1. while:先判断在执行。 do while:先执行一次,在判断。

  1. const int *p = &a;指针的指向可以改,但是指针指向的值不可以改。p = &b √ *p = 20 ×

int * const p = &a; 指针的指向不可以改,但是指针指向的值可以改。p = &b × *p = 20 √

p = 地址,*p = 值

  1. 值传递:若改变形参,实参不会改变。 地址传递:若在所调用函数中改变值,主函数中所对应的值也相应改变。

二、进阶

2.1四个区:代码区,全局区,栈区,堆区

程序运行前:

代码区:存放二进制的代码;共享,只读。

全局区:存放全局变量,静态变量(static),和全局常量。 局部变量和局部常量存放在其他地方。

程序运行后:

栈区:栈区的数据由编译器管理和释放。 用完了就直接释放

堆区:堆区的数据由程序员管理和释放,若程序员不是放,程序结束时由编译器释放。用完了不会自动释放 (new-delete)

new返回的是一个地址。

2.2、引用

10.引用:给变量起别名。 数据类型 &别名 = 原名

引用传参数时,形参改变,实参也会改变。

本质是 int * const p 指针常量

2.3、函数默认值

11.函数默认值

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//函数默认值

//1.如果某个位置参数有默认值,那么从这个参数,从左往右,都必须有默认值。
//2.函数声明和函数实现只能有一个有默认值。
int fun(int a, int b = 30, int c = 40) {
    return a + b + c;
}
int main() {
    int a = fun(10,10);
    cout << a<< endl;
}

2.4 函数重载

12.函数重载满足条件:

  1. 同一个作用域下。

  1. 函数名相同。

  1. 函数参数的类型不同或个数不同,或顺序不同。

2.3函数封装

12.封装

#include <iostream>
#define  _CRT_SECURE_NO_WARNINGS
using namespace std;
#define PI 3.14
//class代表一个类,类+类名

/*
三种权限:
    公共权限 public     成员类内可以访问,类外可以访问
    保护权限 protected    成员类内可以访问,类外不可以访问(父亲可用,子也可用)
    私有权限 private    成员类内可以访问,类外不可以访问(父亲可用,子不可用)
*/
class Circle {
    //访问权限
public:
    //类中的属性和行为都成为行为
    //属性==成员属性或成员变量
    //行为==成员函数或成员方法
    //属性
    int m_r;
    //行为
    double calcutateZC() {
        return 2 * PI * m_r;
    }
};
int main() {
    //实例化(通过一个圆类创建一个对象)
    Circle c1;
    c1.m_r = 10;
    cout << c1.calcutateZC() << endl;
}

struct和class的区别

class默认权限为private

struct默认权限为public

2.4构造函数和析构函数

13.

构造函数类名(){}

1.没有返回值也不写void

2.函数名和类名相同

3.有参数也可以重载

4.函数在调用对象时会自动调用构造,无需手动调用

析构函数 ~类名(){}

1.没有返回值也不写void

2.函数名称和类名相同,前面加~

3.没有参数,不可以重载

  1. 程序在销毁对象前会自动调用析构函数。

  1. 构造函数的分类和调用

按参数分类:无参构造(默认构造)和有参构造

按类型分类:普通构造 拷贝构造函数

调用:括号法,显示法,隐式转换法

2.5拷贝函数

2.6浅拷贝和深拷贝

2.7初始化列表

#include <iostream>
#define  _CRT_SECURE_NO_WARNINGS
using namespace std;
class person {
public:
    int m_a;
    int m_b;
    int m_c;
    //初始化
    person(int a, int b, int c) :m_a(a), m_b(b), m_c(c) {

    }
};
int main() {
    person p(10, 50, 30);
    cout << p.m_a<<endl;
    cout << p.m_b << endl;
    cout << p.m_c<<endl;
}

2.8成员对象

2.9静态成员变量和静态成员函数

所有对象共享一份数据,当由成员改变数据的值时,其他成员所得到的数据也相应改变。

类外初始化 int person::m_a ::表示该类下的属性

类内定义,类外初始化

静态成员变量有访问权限:public,private,protected。

静态成员函数

静态成员函数只能访问静态成员变量,不能访问非静态成员变量

静态成员函数有访问权限:public,private,protected。

2.10 成员变量和成员函数分开存储

只有非静态成员变量的地址是紧挨着类的起始地址存储的。

非静态成员变量是属于类的对象上的。

静态成员变量,非静态成员函数,静态成员函数都是不属于类的对象上的。

2.11 this指针

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class person{

    
public:
    //this指针指向被调用的成员函数所属的对象
    //this指针现在指向p1   
    person(int age) {
        this->age = age;
    }
    //this是指向p2的指针,*this就是指向p2的本体

    person& personAddAge(person &p) {
        this->age += p.age;
        return *this;
    }
    int age;
};
void test01() {
    person p1(18);
    cout << "p1的年龄为:" << p1.age << endl;
}
void test02() {
    person p1(10);
    person p2(10);
    p2.personAddAge(p1).personAddAge(p1);
    cout << "p1的年龄为:" << p2.age << endl;
}
int main() {
    test01();
    test02();
}

this指针的本质是指针常量,指针的指向是不可修改的,所指的值是可以修改的。

2.12 空指针访问成员函数

2.13 常函数和常对象

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class person {
public:
    //加const之后,函数内成员变量的值不可修改
    void showPerson() const {
        //m_ageA = 100;
        m_ageB = 100;
    }
    int m_ageA;
    mutable int m_ageB;//加上mutable之后,常函数中的成员变量就可以修改了
};
int main() {
    //常对象
    //常对象只能调用常函数,不能调用普通的成员函数
    const person p1;
    p1.m_ageA = 100;
    p1.m_ageB = 100;
}

2.14 友元 friend

可以访问私有的内容

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Building;
class Person {
public :
    Person();
    Building * building;
    void visit1();
    void visit2();
};
class Building {
    //友元类
    friend class Person;
    //友元成员函数
    friend void Person::visit2();
public:
    Building();
    string sittingRoom;
private:
    string bedRoom;
};
Building::Building() {
    sittingRoom = "客厅";
    bedRoom = "卧室";
}
Person::Person() {
    building = new Building;
}
void Person::visit1() {
    cout << building->sittingRoom << endl;
    //cout << building->bedRoom << endl;
}
void Person::visit2() {
    cout << building->sittingRoom << endl;
    cout << building->bedRoom << endl;
}

int main() {
    Person p;
    p.visit1();
}

2.15 继承

语法:class 子类 :继承方式 父类

子类:也称派生类

父类:也称基类

继承方式:公共继承,保护继承,私有继承

多继承: class 子类:继承方式 父类1,继承方式 父类2

2.16 多态

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
/*
动态多态:
1、有继承关系
2、子类重写父类函数
*/
class Animal {
public:
     virtual void speak() {  //虚函数
        cout << "动物在说话" << endl;
    }
};
class Cat :public Animal {
public:
    //子函数重写父函数  
    //重写:函数返回值类型相同,函数名,函数列表完全相同
    void speak() {
        cout << "小猫在说话" << endl;
    }
};
//运行时才确定函数的地址。
void doSpeak(Animal &animal) {
    animal.speak();
}
int main() {
    Cat cat;
    doSpeak(cat);
}

当子类重写虚函数时,子类中的虚函数表内部会替换成子类的虚函数地址

当父类的指针或引用指向子类时,发生多态

Animal &animal = cat;

animal.speak();

2.17 纯虚函数和抽象类

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class base {
public:
    //纯虚函数
    //1.只要有一个纯虚数,这个类就成为抽象类
    // 抽象类特点:
    // 1、无法实例化对象
    // 2、抽象类的子类,必须重写父类中的纯虚函数,否则也无法实例化对象
    virtual void func() = 0;
};
class son:public base {
    virtual void func() {
        cout << "shixian" << endl;
    }
};
void test01() {
    //new的是谁,调用的就是那个函数
    base* b = new son;
    b->func();
}
int main() {
    test01();
}

2.18 虚析构和纯虚析构

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class base {
public:
    virtual void speak() = 0;
    base() {
        cout << "base 构造" << endl;
    }
    虚析构
    //virtual ~base() {
    //    cout << "base 析构" << endl;
    //}
    //纯虚析构
    //纯虚析构需要类内声明,类外实现
    virtual ~base() = 0;
};
base::~base() {
    cout << "base析构" << endl;
}
class cat :public base {
public:
    cat(string name) {
        cout << "cat构造" << endl;
        m_name = new string (name);
    }
    void speak() {
        cout << *m_name<<"小猫在说话" << endl;
    }
    ~cat() {
        if (m_name != NULL) {
            cout << "cat构造函数" << endl;
            delete m_name;
        }
    }
    string *m_name;
};
int main() {
    base *b = new cat("tom");
    b->speak();
    delete b;
}

2.19 写文件

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//1、包含头文件
#include<fstream>
void test() {
    //2、创建流对象
    ofstream ofs;
    //3、指定路径和打开方式
    ofs.open("test.txt",ios::out);
    ofs << "123" << endl;
    ofs.close();
}
int main() {
    test();
}

三、提高

3.1模板

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
template<typename T>
void MYswap(T& a, T& b) {
    T temp = a;
    a = b;
    b = temp;
}
int main() {
    int a = 10;
    int b = 20;
    MYswap(a,b);
    cout << a << "   " << b << endl;
}

模板注意事项:

  1. 自动类型推导,必须推导出一致的数据类型T才可以使用

  1. 模板必须要确定出T的数据类型,才可以使用。

普通函数和模板的调用规则:

  1. 如果函数模板和普通函数都可以调用,优先调用普通函数

  1. 可以通过空模板参数列表的方式,强制调用函数模板

  1. 函数模板也可以重载

  1. 函数模板可以产生更好的匹配,优先调用函数模板

3.2类模板

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
template<class nameType,class ageType>
class person {
public:
    person(nameType name, ageType age) {
        m_name = name;
        m_age = age;
    }
    void showPerson() {
        cout << "姓名是:" << m_name << "  年龄是:" << m_age << endl;
    }
    nameType m_name;
    ageType m_age;

};
void test() {
    person<string,int>p1("bob", 18);
    p1.showPerson();
}
int main() {
    test();
}
  1. 类模板:没有推导参数

  1. 类模板在模板参数列表中可以有默认参数

四STL

4.1、string拼接字符串

4.2String查找和替换

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
void test01() {//查找和拼接
    string str1 = "abcdefgfg";
    int pos = str1.find("fg");//find有左往右找
    cout << pos << endl;

    int pos1 = str1.rfind("fg");//rfind从右往左找
    cout << pos1 << endl;
}
void test02() {//替换
    string str = "abcdefg";
    //从1号位置起,3个字符,替换为"1111";
    str.replace(1, 3, "1111");
    cout << str << endl;
}
int main() {
    //test01();
    test02();
}

4.3、string字符串比较

按ASCII值比较

str1.compare(str2);

4.4、string字符存取

str[] 或者 str.at[]

4.5字串

substr(起始位置,字符个数)

4.5vector 数组(顺序表)

#define  _CRT_SECURE_NO_WARNINGS
#include<vector>
#include<iostream>
using namespace std;
void printVector(vector<int>&v) {
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << "  ";
    }
    cout << endl;
}
void test() {
    vector<int>v1;
    //尾插法
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
    v1.push_back(60);
    printVector(v1);
    //插入
    v1.insert(v1.begin(), 100);
    printVector(v1);
    v1.insert(v1.begin(),2, 1000);
    printVector(v1);
    //删除
    v1.clear();
    printVector(v1);
}
int main() {
    test();
    return 0;
}

v.reserve() 预留空间

4.3deque容器(顺序表)

4.4 stack容器(栈)

4.5 queue容器(队列)

4.6list容器 (链表)

sort//排序

reverse//反转

4.7 set和multiset 容器 (二叉树和二叉排序树)

set不可以插入重复的数,multiset可以插入重复的数

插入数据使用 insert

set特点:

  1. 所有元素插入时自动排序

  1. 重复的数只会有一个

4.8队组

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
void test() {
    pair<string, int> p = make_pair("Tom", 20);//两个值成对出现
    cout << p.first << "  " << p.second << endl;
}
int main() {
    test();
}

4.9map和multimap

队组

4.10 算数仿函数

算数函数名<类型>对象名

例如:

plus<int> p;
p(10,20);

4.11. 关系仿函数

大于:greater

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
using namespace std;
void test() {
    vector<int>v;
    for (int i = 0; i < 10; i++) {
        v.push_back(i);
    }
    //关系仿函数  greater
    sort(v.begin(), v.end(), greater<int>());
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
        cout << *it << "  ";
    }
}
int main() {
    test();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值