C++基础

基础知识点

一个简单的程序

#include "iostream"

using namespace std;

int main() {
    cout << "hello world" << endl;
//    system("pause"); // 这个应该只在windows有效
     cout<<"请按任意键继续";
     cin.ignore();
    return 0;// 可以不写,编译器会自动加上
}

标准形式

int main(int arg,char* argv[]) {
    return 0;
}

命名空间

区分同名变量或函数

#include "iostream"

using namespace std;

namespace stu {
    void sort() {
        cout << "stu sort" << endl;
    }
}

namespace sta {
    void sort() {
        cout << "stu sta" << endl;
    }
}


int main(int arg, char *argv[]) {
    stu::sort();
    sta::sort();
    cin.ignore();
    return 0;
}

c++空间申请与释放

#include "iostream"

using namespace std;

int main(int arg, char *argv[]) {
    int *a = new int(1);
    cout << *a;
    delete a;
    return 0;
}
// new  和 delete 可以出发构造和析构

引用

给变量起别名

本质:指针常量(指向不可变,指向的值可以变)

#include "iostream"

using namespace std;

int main(int arg, char *argv[]) {
    int a = 12;
    int &c = a;
    c = 39;
    cout<<c;
    const int &d= a;// 常量修饰的有不可变了
    return 0;
}

其他类型的引用

int main(int arg, char *argv[]) {
    /// 数组的引用
    int arr[12];
    int (&p)[12] = arr;

    /// 二维数组引用
    int arr2[2][3];
    int (&p2)[2][3] = arr2;


    /// 指针的引用
    int b = 12;
    int *point = &b;

    int* &p3 = point;
    *p3 = 32;
    return 0;
}

引用当作函数参数

#include "iostream"

using namespace std;
void fun(int &a){
    cout<<sizeof (a)<<endl;
    a = 3;
}
int main(int arg, char *argv[]) {
     int b = 12;
    fun(b);
    cout<<b<<endl;
    return 0;
}

交换两个值

#include "iostream"

using namespace std;

void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

void swap1(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(int arg, char *argv[]) {
    int a = 13;
    int b = 14;
    swap(a, b);
    cout << " a " << a << "  b  " << b << endl;
    swap1(&a, &b);
    cout << " a " << a << "  b  " << b << endl;
    return 0;
}

引用与指针的区别

  1. 引用声明就必须初始化
  2. 引用初始化后就不能引用其他空间了,指针可以指向其他空间
  3. 引用不占存储空间,指针占空间
  4. 引用效率更高,指针间接操作
  5. 引用更安全,指针可以偏移
  6. 指针更灵活,直接操作地址,指针更通用c语言和c++都行

&的三种作用

  1. 表示引用
  2. 表示取地址
  3. 表示位与运算

函数特性

函数参数默认值

#include "iostream"

using namespace std;

void func(int a = 333){
    cout<<a<<endl;
}
int main(int arg, char *argv[]) {
    func( );
    func(222);
    return 0;
}

// 如果是函数声明或定义,在其中一个指定即可

函数重载

函数名称相同,函数参数个数、类型、顺序不同

成员变量和成员函数分开存储 在c++中,类内的成员变量和成员函数是分开存储的 空对象占用内存空间是 1 byte why:每个空对象也分配一个字节空间,是为了区分空对象占内存的位置 每个空对象也应该有一个独一无二的内存地址 只要是空的,占用一个字节,否则,看成员

同时虚函数也是占用内存的

类和对象的声明

定义:具有相同属性和行为的对象的集合

#include "iostream"

using namespace std;


class CPeople {
public:
    int a;

public:
    void fun() {
        cout << "fun" << endl;
    }
};
int main(int arg, char *argv[]) {
    CPeople cp;
    cp.a = 3;
    cp.fun();
    cout << "点击任意键继续";
    cin.ignore();
    return 0;
}

访问修饰符

修饰符
public公开的
protected受保护的(本类,子类)
private私有的(类内)

c++中class 和 struct唯一的区别:成员默认修饰符不同

​ class默认private,struct默认public

友元

访问私有成员

友元函数

#include "iostream"

using namespace std;

class Stu {
    friend void func1();

private:
    int age;

    void fun() {
        age = 12;
        cout << age << endl;
    }
protected:
    void func1(){
        cout << "protected" << endl;
    }
};
// 友元函数
void func1() {
    Stu stu;
    stu.fun();
    stu.func1();
}

int main(int arg, char *argv[]) {

    func1();


    return 0;
}

友元类

#include "iostream"

using namespace std;

class Stu {
    friend void func1();
    friend class Teach;

private:
    int age;

    void fun() {
        age = 12;
        cout << age << endl;
    }

protected:
    void func1() {
        cout << "protected" << endl;
    }
};

// 友元函数
void func1() {
    Stu stu;
    stu.fun();
    stu.func1();
}


// 友元类
class Teach {
public:
    Stu stu2;
    void fun2() {
        stu2.func1();
    }
};


int main(int arg, char *argv[]) {
    Teach t;
    t.fun2();

    return 0;
}

缺点:破坏了类的封装性

构造函数和初始化列表

声明指针不会走构造函数,只有 new Class 的时候才去走构造函数

#include "iostream"

using namespace std;


class Stu {
public:
    int age;

    string name;
public :/// 构造重载
    Stu() {};

    Stu(int age, string name) : age(age), name(name) {};

    Stu(int age);/// 类定义
public:
    void func(int age);
};

/// 这种写法用在多文件的时候
Stu::Stu(int age) {
    this->age = age;
};

void Stu::func(int age) {
    this->age=age;
}

int main(int arg, char *argv[]) {
    Stu stu(3, "张三");
    cout << stu.age << " " << stu.name << endl;
    Stu *stu1 = new Stu(3, "张三");
    cout << stu1->age << " " << stu1->name << endl;
    return 0;
}
#include "iostream"

using namespace std;


class Stu {
/// const 的修饰必须初始化
public:
    int b;
    int &a;

public:
    /// 此时a无效的,c被回收了
    /*Stu(int c) : a(c), b(c) {

    }*/
    /// 此时a无效的,c被回收了
    Stu(int &c) : a(c), b(c) {

    }
};


int main(int arg, char *argv[]) {
    int age = 3;
    Stu stu(age);
    cout<<stu.a<<" "<<stu.b<<endl;
    return 0;
}

析构函数

清理工作,有且只有一个,不能有参数,默认有一个析构函数

#include "iostream"

using namespace std;


class Stu {
public:
    Stu() {
        cout << "构造函数" << endl;
    }


    ~Stu() {
        cout << "析构函数" << endl;
    }
};


int main(int arg, char *argv[]) {
    Stu stu;
    return 0;
}

指针对象delete和临时对象

#include "iostream"

using namespace std;


class Stu {
public:
    Stu() {
        cout << "构造函数" << endl;
    }


    ~Stu() {
        cout << "析构函数" << endl;
    }
};


int main(int arg, char *argv[]) {
    Stu *stu = new Stu();
    /// 遇到delete才回去调用析构
    delete stu;
  
   /// 临时对象
    Stu(); // 只是当前行作用域
    return 0;
}

#include "iostream"

using namespace std;


class Stu {
public:
    int *pp;
public:
    Stu() {
        pp = new int(10);
        cout << "构造函数" << endl;
    }
    ~Stu() {
        // 自己的new的对象必须释放
        delete pp;
        cout << "析构函数" << endl;
    }
};


int main(int arg, char *argv[]) {

    return 0;
}

new delete 和 malloc free区别

new delete 在c++中可以分别出发构造函数和析构函数

malloc free 不会触发

其他没有区别

this指针

作用:

​ 区分同名的

​ 是指向当前对象的指针,所以我们可以通过指针,访问成员

const成员和static成员

常函数

只有成员函数,可以加const

特点:

​ 可以使用成员属性,不可修改,可以使用

​ 常函数只能调用常函数

​ 常对象只能调用常函数

#include "iostream"

using namespace std;

class Stu {
    int a;
public :
    Stu() {
        a = 23;
    }

public:
    void show() const {
        update();
        cout << "show hello world" << a << endl;
    }

    void update() const {
    }

    void show1() {}

};


int main(int arg, char *argv[]) {
    const Stu stu;
    stu.show();
    return 0;
}

静态成员

静态属性类外初始化

常量静态整型可以类内直接初始化

#include "iostream"

using namespace std;


class Stu {
public :
    static int a;
    /// const的修饰的静态整型可以类内直接初始化
    const static int b = 3;
};

int Stu::a = 3;

int main(int arg, char *argv[]) {
    Stu stu;
    return 0;
}

拷贝构造

本质是构造函数

默认拷贝是浅拷贝

#include "iostream"

using namespace std;


class Stu {
public:
    int a = 0;
public :
    Stu() {}
    /// 定义构造
    Stu(const Stu &a) {
     this->a=a.a;
    }
};

int main(int arg, char *argv[]) {
    Stu s0;
    Stu s1(s0);   s1.a++;
    Stu s2 = s1;
    Stu s3 = Stu(s1);
    Stu *s4 = new Stu(s1);

    cout<<s1.a<<endl;
    cout<<s2.a<<endl;
    cout<<s3.a<<endl;
    cout<<s4->a<<endl;

    return 0;
}

深拷贝

有指针成员的话

利用 new 和 memocp ,strcpyd 等开辟新的内存

内联函数

函数声明要加inline

函数定义要加inline,注意只写声明位置不管事

作用:用相应的代码替换调用

​ 比常规函数稍快,代价占用更多内存

inline void fun(){
}

虽然定义了内联函数,具体调用取决于编译器

#include "iostream"

using namespace std;

#define SUM(x) x*x;

inline void fun(int i) {
    cout << (i * i);
}

int main(int arg, char *argv[]) {
    cout << SUM(2 + 3);

    fun(2 + 3);
    return 0;
}

类与内联合函数

类内定义的都是内联函数(包括显示和隐式)

定义在外:

​ 有 inline是内联

​ 没有inline不是内联

内联函数与多文件:通常内联函数写在文件里

运算符重载

关键字operator

有四种运算符无法重载: :: 、.* 、. 、?:

类外重载

#include "iostream"

using namespace std;

class Stu {
public :
    int age;
    double score;

    Stu() {
        age = 3;
        score = 10.0;
    }
    Stu(int age):age(age){};
};

int operator+(Stu &s1, int a) {
    return s1.age + a;

}

int operator+(int a, Stu &s1) {
    return s1.age + a;

}
Stu operator+(Stu &s1, Stu &s2) {
    return Stu(s1.age + s2.age);

}

int main(int arg, char *argv[]) {
    Stu s1,
            s2;
    cout << 12 + s1 + s1 + s2 + 12<< endl;
    return 0;
}

类内重载

#include "iostream"

using namespace std;

class Stu {
public :
    int age;
    double score;

    Stu() {
        age = 3;
        score = 10.0;
    }

    Stu(int age) : age(age) {};


    int operator+(int a) {
        return this->age + a;

    }

    Stu operator+(Stu &s2) {
        return Stu(this->age + s2.age);

    }

};

/*
int operator+(Stu &s1, int a) {
    return s1.age + a;

}

int operator+(int a, Stu &s1) {
    return s1.age + a;

}
Stu operator+(Stu &s1, Stu &s2) {
    return Stu(s1.age + s2.age);

}*/

int main(int arg, char *argv[]) {
    Stu s1,
            s2;
    /// 左侧必须是个类,所以第二种无法实现
    cout << s1 + 12 << endl;
//   cout<<12+s1<<endl;
    return 0;
}

个人总结:

​ 一元运算符,建议类内

二元运算符,可以类外,也可以类内

​ = 、[]、()、->必须是类内

关系运算符

#include "iostream"

using namespace std;

class Stu {
public :
    int age;

    Stu(int age) : age(age) {}
    /// 这个更适合类内
    bool operator>=(Stu &s2) {
        return this->age >= s2.age;
    }
};


int main(int arg, char *argv[]) {
    Stu s1(90),
            s2(60);
    cout << (s1 >= s2) << endl;
    return 0;
}

多练练就会了,不是很难,坚持

#include "iostream"

using namespace std;

class Stu {
public :
    int age;

    Stu(int age) : age(age) {}

};

Stu operator-(Stu &s){
    return Stu(-s.age);
}

int main(int arg, char *argv[]) {
    Stu s1(90),
            s2(60);
    cout <<  (-s1).age<<endl  ;
    return 0;
}

输入、输出运算符重载

#include "iostream"

using namespace std;

class Stu {
public :
    int age;

    Stu(int age) : age(age) {}

};

// 返回自己,所以不会释放内存
ostream& operator<<(ostream& os,const Stu& stu){
    os<<stu.age;
    return os;
}

// 返回自己,所以不会释放内存
istream& operator>>(istream& is,const Stu& stu){
    if (is.fail()){
        cout<<"输入失败"<<endl;
        return is;
    }
    is>>stu.age;
    return is;
}

int main(int arg, char *argv[]) {
    Stu s1(90),
            s2(60);
//    cout<<s1<<s1<<endl;

    cin>>s1;
    cout<<s1.age<<endl;
    return 0;
}

赋值运算符

#include "iostream"

using namespace std;

class Stu {
public :
    int age;

    Stu(int age) : age(age) {}

    int operator=(int a) {
        return this->
                age + a;
    }

    Stu &operator+=(int a) {
        this->
                age += a;
        return *this;
    }
};


int main(int arg, char *argv[]) {
    Stu s1(90),
            s2(60);
     
    (s1 += 30) += 30;
    cout<<s1.age<<endl;

    return 0;
}

下标

#include "iostream"

using namespace std;

class Stu {
public :
    int age;

    Stu(int age) : age(age) {}

    int operator[](int index) {
        switch (index) {
            case 0:
                return this->
                        age;
        }
        return -1;
    }


};


int main(int arg, char *argv[]) {
    Stu s1(90),
            s2(60);

    cout << s1[1] << endl;

    return 0;
}

 

重载类型转换

#include "iostream"

using namespace std;

class Stu {
public :
    int age;
    Stu(int age) : age(age) {}
  /// 用常函数,防止修改
    operator int() const {
        return this->age;
    }
};


int main(int arg, char *argv[]) {
    Stu s1(90),
            s2(60sl
    cout<<(int)s1<<endl;

    return 0;
}

继承

#include "iostream"

using namespace std;


class People {
public:
    void study() {
        cout << "学习" << endl;
    }

protected:
    void run() {
        cout << "运动" << endl;
    }
private:
    void showId(){
        cout<<"showId"<<endl;
    }
};

class Child : public People {
public:
    void gotoPark() {
        cout << "gotoPark" << endl;
    }
};

int main(int arg, char *argv[]) {
    Child child;
    child.study();
    child.gotoPark();
    return 0;
}

继承修饰符

修饰符
public父类怎么样,子类就怎么样
protected父类public降级protected
private父类public、protected降级private

如果不写默认private

构造与析构函数

#include "iostream"

using namespace std;


class People {

public:
    People() {
        cout << "People 构造函数" << endl;
    }

    People(int a) {
        cout << "People 构造函数" << a << endl;
    }

public:
    void study() {
        cout << "学习" << endl;
    }

protected:
    void run() {
        cout << "运动" << endl;
    }

private:
    void showId() {
        cout << "showId" << endl;
    }

public:
    ~People() {
        cout << "People 析构函数" << endl;
    }
};

class Child : public People {

public:
    Child() {
        cout << "Child 构造函数" << endl;
    }

public:
    void gotoPark() {
        this->study();
        cout << "gotoPark" << endl;
    }

    ~Child() {
        cout << "Child 析构函数" << endl;
    }
};

int main(int arg, char *argv[]) {
    Child child;
//    child.study();
    child.gotoPark();
    return 0;
}

友元不能被继承

多态

多态是一种泛型编程思想

虚函数是实现这个思想的语法基础:父类的指针调用子类的函数

重写

#include "iostream"

using namespace std;


class People {
public:
    /// 使用virtual实现子类方法重写
    virtual void show() {
        cout << "People" << endl;
    }


};

class Child : public People {

public:
  /// 子类重写后,这个方法前面 默认有个 virtual,可以再找个当前类的子类测试
    void show() {
        cout << "Child" << endl;
    }
};

int main(int arg, char *argv[]) {
    People *p1 = new Child();
    p1->show();
    return 0;
}

虚析构

释放父类指针,调用父类析构的同时 也要调用子类析构

#include "iostream"

using namespace std;


class People {
public:
   virtual ~People() {
        cout << "父类虚析构" << endl;
    }

};

class Child : public People {
public:
    ~Child() {
        cout << "子类虚析构" << endl;
    }

};

int main(int arg, char *argv[]) {
    People *p1 = new Child();
    delete p1;
    return 0;
}

纯虚函数

纯虚函数所在的类叫做抽象类

子类继承时必须实现

#include "iostream"

using namespace std;


class People {
public:
    virtual void show() = 0;

};

class Child : public People {
public:
    void show() override {
        cout << "hello world" << endl;
    }

};

int main(int arg, char *argv[]) {
    People *p1 = new Child();
    p1->show();
    return 0;
}

虚继承

解决棱形继承问题

了解即可

#include "iostream"

using namespace std;


class A{
public:int a;
public:A(){
    a= 10;
}
};
class B:virtual public A{};
class C:virtual  public A{};
class D:public B,public C{};

int main(int arg, char *argv[]) {
    D d;
    cout<<d.a<<endl;
    return 0;
}

其他内容

联编

联编:就是将模块或者函数合并在一起生成可执行代码的处理过程,(函数调用),按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编

静态联编:指在编译阶段将函数实现和函数调用关联起来

​ 例子:普通函数调用

动态联编:指在程序执行的时候才将函数调用和函数调用调用关联

动态联编是针对c++的多态的,c语言里全部都是静态联编

#include "iostream"

using namespace std;


class A {
public:
   virtual void fun() {
        cout << "fun  " << endl;
    }
};
class B:public A{
public:
    void fun() override{
        cout<<"B fun"<<endl;
    }
};
int main(int arg, char *argv[]) {
    A* a;
    int b;
    cin >> b;
  /// 主要看代码,这里不确定
    switch (b) {
        case 1:a = new A;
            break;
        case 2:a = new B;
            break;
    }
    return 0;
}

异常

#include "iostream"
#include "cstdlib"

using namespace std;

void fun(int a) {
    if (0 == a) {
        abort();// 异常终止
    }
}

int main(int arg, char *argv[]) {
    try {
//        本来想看个 /0 异常,很神奇
//        int a = 10 / 0;
//        cout << a << endl;
        throw 0;
    } catch (int b) {
        cout << "异常捕获" << endl;
    } catch (char c) {
        cout << "异常捕获" << endl;
    } catch (...) {
        cout << "default erro" << endl;
    }
    return 0;
}

内部类

#include "iostream"
#include "cstdlib"

using namespace std;

class Out {
public:
    int a;

    Out() {
        a = 12;
    }

public:
    class In {
    public:
        int b;
        In() {
            /// 内部类不能直接使用外部类的成员,还是需要对象的方式
            Out o;
            cout<<o.a<<endl;
            b = 13;
        }
    };
};

int main(int arg, char *argv[]) {
    Out::In in;
    cout<<in.b<<endl;
    return 0;
}

类型转换

旧式类型转换:(type)vlaue

新式类型转换:static_cast

​ const_cast

​ dynamic_cast

​ reinterpret_cast

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值