C++杂记

new和引用&

int main() {
    int res=test(1);
    
    //在堆区创建整形数据的数组,需要手动delete,否则内存泄露
    int* arr=new int[10];
    for(int i=0;i<10;i++){
        arr[i]=i;
    }
    delete[] arr;

    cout<<endl;

    int a=1;
    //a b均指向同一地址,改一则二动
    //必须在创建int&时必须初始化,=能赋值操作不能更改引用
    int &b=a;
    b=2;
    
    int c=1;
    const int& d=c;
    //d=2  const修饰后d就不能修改
    return 0;
}

函数重载和占位符

// 有默认值参数后面需要有默认值
// 函数声明和函数中默认值只能出现一次
int test(int num1,int num2,int num3=3);
// 占位符不能出现在函数声明中,并且占位符可以有默认值,在函数调用时不用手动赋值
int test(int num1,int ,int num2,int num3,int=4){
    return num1+num2+num3;
}

// 函数重载只与形参列表中个数,顺序和类型有关,函数返回值不与重载有关
int test(int num1,int num2=2){
    return num1+num2;
}
// 函数重载调用时要注意调用的是哪一个,不能出现调用不明确现象
//const只有修饰引用时才能作为重载条件
void test(const int& num){
    cout<<"const int num"<<endl;
}

void test(int &num){
    cout<<"int num"<<endl;
}

int main() {
    int a=0;
    test(a);//调用int& 变量传值首先选择int&,不是const int&
    test(1);//调用const int& 说明const int&可以直接赋值常数
    return 0;
}

权限修饰

public	能继承给子类,子类和类外均可访问
protected	能继承给子类,子类可访问,类外不可访问
private	 能继承给子类,子类和类外均不可访问
类中变量默认private

构造和析构函数

构造函数就是java中的构造器
析构函数是创建对象后销毁对象前最后运行的代码,特点是:前加 ’ ~ ’ ,无参数,无返回值,不可发生重载,自动被调用,只能调用一次
类中自动提供:
1.空参构造器(自定义其他构造器后则不存在,拷贝构造器同)
2.拷贝构造器(只有一个参数为类本身,对于所有的属性进行拷贝)
3.空函数体的析构函数

Person() {
}
Person(Person&person){
    //属性拷贝
}
~Person() {
}

当类中出现其他类成员变量时,成为对象成员,构造顺序是先调用对象成员构造器,后调用本类构造器,析构函数顺序相反

//在创建对象调用空参构造器时,不能加(),否则会被编译器认为函数声明,不会认为创建对象
Person p();//函数声明
Person p;//创建对象

#include <iostream>
#include <string>
#include <list>
using namespace std;
class Person{
private:
    string name="";
    int age=0;
public:
    Person() {}
    Person(int age):age(age){}
    Person(const string &name, int age) : name(name), age(age) {}

    friend ostream &operator<<(ostream &os, const Person &person) {
        os << "name: " << person.name << " age: " << person.age;
        return os;
    }
};
int main() {
    Person();//匿名对象的创建,创建后立即销毁
    Person person1;//空参构造
    Person person2("aa",11);
    Person person3=Person();//空参构造
    Person person4=Person("bb",11);
    Person person5=12;//隐式转换法创建对象,值允许一个参数才能使用
    return 0;
}

类中new注意事项
堆开辟空间需要自己提拷贝函数,防止浅拷贝

#include <iostream>
#include <string>
using namespace std;
class Person{
public:
    int* age;
    Person(int age) {
        this->age=new int(age);
    }
    Person(Person&person){
        //this->age=person.age;
        this->age=new int(*person.age);
    }
    ~Person() {
    	if(age!=NULL){
        	delete this->age;
        	age=NULL;
        }
    }
};

int main() {
    Person person(12);
    // 通过拷贝函数中的this->age=person.age;赋值就会造成两个Person类中的age属性同时指向同一地址
    // 在调用析构函数时对同一地址进行delete,就会报错,所以在拷贝构造时通过this->age=new int(*person.age);进行赋值
    Person person1=person;
    return 0;
}

对象的初始化方式

class Person{
public:
    string name;
    int age;
    //初始化列表初始化属性,在参数列表中填入初始化值
    //形参列表中属性可以不写,这样就会造成也可以使用空参构造器,两用
    Person(string name, int age) : name(name), age(age) {
    }
};

static

static修饰的变量方法和没有static修饰的方法都不属于单个对象,只有没有static修饰的属性属于单个类
class Person{
public:
    //编译阶段分配内存
    //类内声明,类外初始化,共享同一份数据,并不属于某一个对象
    static int num;
    static void fun(){
        //静态方法只能访问静态变量
        num=0;
        cout<<"num = "<<num<<endl;
    }

};
//需要先定义声明static变量的存在,才能在main函数中调用赋值
int Person::num=0;
int main() {
    Person person;
    //两种对static变量进行赋值操作
    person.num=1;
    Person::num=2;
    //两种对static方法进行调用
    person.fun();
    Person::fun();

    return 0;
}

this和const修饰的类和方法

class Person{
public:
    int age;

    Person(int age):age(age) {}

    void show(){
        cout<<"我是没有this关键字的方法"<<endl;
    }
    //this本质是常量指针:Person * const this 所以指向不能改变
    //方法后增加const变成常方法,会使this变成const Person * const this使this指向的值也不能改变
    void showAge()const{
        //this->age=2;报错
        //this=NULL;报错
        cout<<"我会调用this关键字,age = "<<this->age<<endl;
    }
};

int main() {
    Person* person=NULL;
    //空指针对象可以调用类中不涉及属性的方法
    person->show();
    空指针对象不可以调用类中不涉及属性的方法,会空指针异常
    //person->showAge();

    //const修饰是常对象,只能调用常方法,因为其他方法可能会改变属性
    const Person person1(3);
    person1.showAge();
    return 0;
}

friend

友元全局函数
友元类

class Person{
    //允许访问私有权限
    friend void test(Person&person);
    friend class GoodPerson;
private:
    int age;
public:
    Person(int age):age(age){
    }
};

class GoodPerson{
public:
    GoodPerson(){
    }
    void play(Person&person){
        cout<<"age of person is "<<person.age<<endl;
    }
};

void test(Person&person){
    cout<<"age of person is "<<person.age<<endl;
}
int main() {
    Person person(12);
    test(person);
    GoodPerson goodPerson;
    goodPerson.play(person);
    Person person1(11);
    return 0;
}

友元成员函数(严格按照这种顺序)

#include <iostream>
#include <string>
using namespace std;
class Person;

class GoodPerson{
public:
    GoodPerson(){
    }
    void play(Person&person);
};

class Person{
    friend void GoodPerson::play(Person&person);
private:
    int age;
public:
    Person(int age):age(age){
    }
};

void GoodPerson::play(Person&person){
    cout<<"age of person is "<<person.age<<endl;
}

int main() {
    Person person(12);
    GoodPerson goodPerson;
    goodPerson.play(person);

    return 0;
}

operator

运算符重载也可以发生函数重载
+
class Person{
public:
    int age;
    int num;
    Person(int age,int num):age(age),num(num){
    }
    Person operator+(Person&person){
        Person temp(person.age+this->age,person.num+this->num);
        return temp;
    }
};
/*
全局函数重载 + 号
Person operator+(Person&p1,Person&p2){
    Person temp(p1.age+p2.age,p2.num+p2.num);
    return temp;
}
 使用的两种方法:
Person p=operator+(p1,p2);
Person p=p1+p2;

重载举例:
Person operator+(Person&p,int num){
    Person temp(p.age,p.num+num);
    return temp;
}
 */

int main() {
    Person p1(1,3);
    Person p2(1,3);
    //两种使用方式
    Person p3=p1.operator+(p2);
    Person p4=p1+p2;

    return 0;
}
<<
class Person{
public:
    int age;
    int num;
    Person(int age,int num):age(age),num(num){
    }
    //类内部重载<<
    friend ostream &operator<<(ostream &os, const Person &person) {
        os << "age: " << person.age << " num: " << person.num;
        return os;
    }
};

/*
全局函数重载 << 号
ostream &operator<<(ostream &os, const Person &person) {
    os << "age: " << person.age << " num: " << person.num;
    return os;
}
 */

int main() {
    Person p1(1,3);
    Person p2(1,3);
    
    operator<<(operator<<(cout,p1),p2);
    cout<<p1<<p2 <<endl;
    return 0;
}
++
class Person{
public:
    int age;
    int num;
    Person(int age,int num):age(age),num(num){

    }
    //前置++
    Person& operator++(){
        //this->num++;
        (*this).num++;
        return *this;
    }
    //后置++
    Person operator++(int ){
        Person temp=*this;
        this->num++;
        return temp;
    }

    friend ostream &operator<<(ostream &os, const Person &person) {
        os << "age: " << person.age << " num: " << person.num;
        return os;
    }
};


int main() {
    Person p1(1,3);
    Person p2(1,3);

    cout<<p1<<++p1<<endl;
    return 0;
}
== !=
class Person{
public:
    int age;
    int num;
    Person(int age,int num):age(age),num(num){
    }

    bool operator==(Person& person){
        if(this->num==person.num&&this->age==person.age)
            return true;
        else
            return false;
    }
    bool operator!=(Person& person){
        return !this->operator==(person);
    }

    friend ostream &operator<<(ostream &os, const Person &person) {
        os << "age: " << person.age << " num: " << person.num;
        return os;
    }
};


int main() {
    Person p1(1,3);
    Person p2(1,3);
    bool a=p1==p2;
    bool  b=p1!=p2;
    cout<<a<<b<<endl;
    return 0;
}

继承方式

在这里插入图片描述

构造顺序

先造父类后造子类,子类先销毁父类后销毁

重名属性和方法

class Person{
public:
    int age;
    Person(){}
    void show(){
        cout<<"父类show"<<endl;
    }
    static void showStatic(){
        cout<<"static 父类方法"<<endl;
    }
};

class Student:public Person{
public:
    int age;
    Student(int age):age(age){
        //同java,父类要有空参构造器
    }
    void show(){
        //同名调用父类要添加作用域,方法同
        cout<<age<<Person::age<<endl;
    }

};

int main() {
    Student s1(17);
    s1.show();
    //调用父类方法添加作用域
    s1.Person::show();
    //静态方法
    s1.showStatic();
    Student::Person::showStatic();
    return 0;
}

菱形继承

class Person{
public:
    int age;
};
class Man: public Person{};
class Woman: public Person{};
class Student:public Man,public Woman{};

int main() {
    Student student;
    student.Man::age=1;
    student.Woman::age=2;
    return 0;
}
using namespace std;

class Person{
public:
    int age;
};
class Man:virtual public Person{};//虚继承,Person为虚基类
class Woman:virtual public Person{};
class Student:public Man,public Woman{};

int main() {
    Student student;
    //virtual修饰后只存在一个变量,被两类公用,下面三种均值一个
    student.Man::age=1;
    student.Woman::age=2;
    student.age=3;
    //地址相同
    cout<<&(student.Man::age)<<'\n'<<&(student.Woman::age)<<'\n'<<&(student.age)<<endl;
    return 0;
}

多态virtual

class Person{
public:
    int* age;
    Person(){
        this->age=new int(17);
    }
    //有一个virtual修饰的方法该类就是抽象类,无法被实例化,子类要重写该virtual方法
    virtual void  show()=0;
    //纯虚析构需要声明也需要实现
    virtual ~Person()=0;
};
Person::~Person() {
    delete this->age;
    cout<<"Person虚构函数"<<endl;
}
void Person::show() {
    cout<<"父类show方法"<<endl;
}

class Student:public Person{
public:
    int *num;
    Student(){
        num=new int(1);
    }
    void show(){
        cout<<"子类重写的方法"<<endl;
    }

    ~Student(){
        delete num;
        cout<<"Student虚构函数调用"<<endl;
    }
};

int main() {
    //多态:若重写的不是virtual方法,运行的是父类,只有virtual才运行子类
    //virtual修饰后,父类可在类外进行父类方法定义
    //父类指针在调用析构函数时,不会调用子类析构函数,导致子类如果堆区有属性,会内存泄漏
    //为解决子类内存泄漏,需要将父类析构函数进行virtual修饰,并在类外进行析构函数定义,这样也会运行子类析构函数
    Person* person= new Student();
    (*person).show();
    person->Person::show();
    delete person;
    return 0;
}

IO

文本文件

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main() {
    ofstream ofs;
    ofs.open("test.txt",ios::out);
    ofs<<"aaaa"<<endl;
    ofs.close();

    ifstream ifs;
    ifs.open("test.txt",ios::in);
    if(!ifs.is_open()){
        cout<<"打开失败"<<endl;
        return 0;
    }
    string buf;
    while (getline(ifs,buf)){
        cout<<buf<<endl;
    }
    
    /*
    另外三种
     
    char buf[1024]={0};
    while (ifs.getline(buf,sizeof (buf))){
        cout<<buf<<endl;
    }

    char buf[1024]={0};
    while (ifs>>buf){
        cout<<buf<<endl;
    }
     
     char buf;
    while ((buf=ifs.get())!=EOF){
        cout<<buf;
    }
     */
    ifs.close();
    return 0;
}

二进制文件

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

class Person{
public:
    string name;
    int age;

    Person() {}

    Person(string name, int age) : name(name), age(age) {}

    friend ostream &operator<<(ostream &os, const Person &person) {
        os << "name: " << person.name << " age: " << person.age;
        return os;
    }
};

int main() {
    //写入文件
    ofstream ofs("test.txt",ios::out|ios::binary);
    Person person("aaa",12);
    ofs.write((const char *)&person,sizeof(person));
    ofs.close();

    //读入数据
    ifstream ifs("test.txt",ios::in|ios::binary);
    if(!ifs.is_open()){
        cout<<"打开失败"<<endl;
        return 0;
    }
    Person p;
    ifs.read((char*)&p,sizeof (p));
    cout<<p<<endl;
    ifs.close();
    return 0;
}

模板

模板的调用

#include <iostream>
#include <string>
using namespace std;

//typename可换成class
template<typename T>
void sway(T&a,T&b){
    T temp=a;
    a=b;
    b=temp;
    cout<<"template"<<endl;
}
void sway(int&a,int&b){
    int t=a;
    a=b;
    b=t;
    cout<<"int sway"<<endl;
}
int main() {
    int a=1, b=2;

    sway(a,b);//用的int sway
    cout<<a<<b<<endl;
    sway<>(a,b);//用的template sway
    cout<<a<<b<<endl;
    sway<int>(a,b);//用的template sway
    cout<<a<<b<<endl;

    char c='a';
    char d='b';
    sway(c,d);//用的template sway
    cout<<c<<d<<endl;
    return 0;
}

类模板

#include <iostream>
#include <string>
using namespace std;

template<typename T,typename E>
class Person{
public:
    T name;
    E age;
    Person(T name,E age):name(name),age(age){}
    void showType(){
        cout<< "T 类型为"<<typeid(T).name()<<endl;
        cout<< "E 类型为"<< typeid(E).name()<<endl;
    }
    friend ostream &operator<<(ostream &os, const Person &person) {
        os << "name: " << person.name << " age: " << person.age;
        return os;
    }
};
//传参方式1:
void test1(Person<string,int>&person){
    cout<<person<<endl;
}
//传参方式2:
template<class T1,class T2>
void test2(Person<T1,T2>&person){
    cout<<person<<endl;
}
//传参方式3:
template<class T>
void test3(T&person){
    cout<<person<<endl;
}
int main() {
    //<string,int>不能省略
    Person<string,int> person("小明",12);
    person.showType();
    test1(person);
    test2(person);
    test3(person);
    return 0;
}

模板的继承

#include <iostream>
#include <string>
using namespace std;

template<typename T,typename E>
class Person{
public:
    T name;
    E age;
    Person(){}
    Person(T name,E age):name(name),age(age){}
};

template<typename T,class T1>
class Student:public Person<string,T1>{
public:
    T grade;
    Student(string name, T1 age, T grade){
        this->name=name;
        this->age=age;
        this->grade=grade;
    }
};

int main() {
    Person<string,int> person("小明",12);
    Student<int ,int >student("小红",17,9);
    return 0;
}

string

string赋值

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s1;
    string s2(2,'w');
    string s3(s2);
    const char * arr="aaa";
    string s4(arr);
    cout<<s1<<endl;//空
    cout<<s2<< endl;//ww
    cout<<s3<<endl;//ww
    cout<<s4<<endl;//aaa
    return 0;
}

string方法

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s1="aaa";
    string s2="bbb";
    s1+=s2;
    s1+s2;
    s1.append("111");
    s1.append("2222",3);//前三个
    s1.append("abcdef",1,2);//从1开始的后两个
    int pos=s1.find("11");
    s1.find("11",3);
    s1.rfind("2");//右
    cout<<s1<<endl;
    s1.replace(1,3,"wwwww");//1到3包括三换成wwwww
    int a=s1.compare(s2);//比较大小
    int b=s1.size();
    s1.insert(1,"aaaaaaaa");
    s1.erase(1,3);//从一开始后三个元素
    string s=s1.substr(1,2);//下标为1后的两个
   
    return 0;
}

vector

在这里插入图片描述

#include <iostream>
#include <string>
#include <vector>

using namespace std;
void print(vector<int>v){
    for(int i : v){
        cout<<i<<endl;
    }
    cout<<endl;
    /*
    for(vector<int>::iterator iterator=v.begin();iterator!=v.end();iterator++){
        cout<<*iterator<<endl;
    }
    */
}
int main() {

    vector<int> v1{1,2,3,4};
    vector<int> v2(v1.begin(),v1.end());
    vector<int> v3(2,4);//3个4
    vector<int> v4(v2);
    print(v4);
    v4.resize(10);//指定大小
    v4.capacity();//容量
    v3.size();//大小
    int c=v1.back();//最后一元素
    v1.swap(v2);//交换
    v1.swap(v2);//可以收缩内存

    return 0;
}

list(链表)

size()
empyt()
resize()
push_back()
pop_back()
push_front()
pop_front()
insert()
clear()
erase()
remove()
迭代器支持iterator++或- -
不支持随机

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「 25' h 」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值