5-C++的list列表、deque队列、迭代器、继承、权限

本文详细介绍了C++中的list和deque容器的使用,包括插入、删除和迭代器操作。同时,文章讲解了迭代器在遍历容器时的重要性,并展示了如何利用迭代器进行元素访问和修改。此外,文章还涉及了C++中的继承概念,包括构造函数的透传和委托,以及成员访问权限的控制。
摘要由CSDN通过智能技术生成

目录

1.list列表

 list列表应用:选猴王

2.deque队列

 键---值   

3.迭代器

4.继承

4.1继承中的构造函数

透传函数

委托构造

5.权限


1.list列表

list是双向的列表,高效的插入和删除,但是读取效率稍低。不支持下标操作,用迭代器来操作

#include <iostream>
#include <list> //写明头文件
using namespace std;

int main(){
    list<string> lis; //创建空list列表
    //尾部增加
    lis.push_back("AA");
    lis.push_back("BB");
    lis.push_back("CC");
    lis.push_back("DD"); //AA BB CC DD

    //尾部删除
    lis.pop_back(); //AA BB CC

    //头部增删
    lis.push_front("tom"); //tom AA BB CC
    lis.pop_front(); //AA BB CC


    //lis.erase(lis.begin()+2); //vector的方法不可用
    //list列表迭代器不支持随机访问 list迭代器访问最后一个和前一个是可以的
    lis.erase(++lis.begin()); //AA CC

    lis.push_back("EE");
    lis.push_back("FF");   //AA CC EE FF

    //插入
    list<string>::iterator it=lis.begin();
    advance(it,2);  //再往后移动2位
    cout<<*it<<endl;  //EE
    lis.insert(it,"hello");  //AA CC hello EE FF
    
    //删除最后的元素
    lis.erase(--lis.end()); //AA CC hello EE
    //lis.erase(lis.end());  直接这样可能会全删除

    for(string s:lis){
        cout<<s<<" ";
    }cout<<endl;

}
#include <iostream>
#include <list> //写明头文件
using namespace std;
int main()
{
    list<string> lis;
    lis.push_back("AA");
    lis.push_back("BB");
    lis.push_back("CC");
    lis.push_back("DD"); //AA BB CC DD
    
    list<string>::iterator it=lis.begin();
    advance(it,1);
    cout<<*it<<endl; //BB
    
    //删除
    it=lis.erase(it); 
    //删除之后会返回删除元素后面的位置的迭代器。但是需要迭代器变量重写来接收    
    cout<<"删除之后:"<<*it<<endl;

    //lis.erase(it);  再cout<<*it<<endl;  出来的是乱码
    //it=lis.erase(it); 再cout<<*it<<endl;  出来的是下一个字符串  
    //比如AA BB CC DD  it是BB,it=lis.erase(it);  再cout<<*it<<endl;  出来的是CC
    //结果是AA CC DD
    
    
    for(string s:lis)
    {
    cout<<s<<" ";
    }

}

 list列表应用:选猴王

有n只猴围城一圈,从1开始报数,数到m的就离开。直到最后一只猴,这只猴就是猴王

#include <iostream>
#include <list> //写明头文件
using namespace std;
int main()
{
    int n,m;
    cin>>n>>m; //n 总数  查到m删除
    list<int> monkeys;
    for(int i=1;i<=n;i++)   //5
    {
        monkeys.push_back(i);
    }
    list<int>::iterator it=monkeys.begin();
    //当个数=1的时候停止  所以>1的时候循环
    while(monkeys.size()>1){
        for(int i=1;i<m;i++){   //m=3
            it++;
            //如果加到end()时证明已经到末尾了,转成开头的元素继续报数
            if(it==monkeys.end()){
                it=monkeys.begin();
                }
            }
        it=monkeys.erase(it);
        //删除之后如果到了end()位置 ,应转到开头元素位置
        if(it==monkeys.end()){
            it=monkeys.begin();
        }
        cout<<"准备删除的元素是:"<<*it<<endl;
        
        for(int j:monkeys)
        {
            cout<<j<<" ";
        }
        cout<<endl;
    
}
cout<<"猴王编号:"<<monkeys.front()<<endl;
}

2.deque队列

API兼顾vector和list,性能在两者之间 ,和前面通用;

关联容器

元素之间位置并没有严格物理上的顺序关系,不能指明元素的位置。但内部会自动的排序;

常见的关联容器:map(键值对) mulitmap(多重键值对)

#include <iostream>
#include <map>
using namespace std;
int main(){
    map<string,int>mp;
    cout<<mp.empty()<<endl;  //1空 0非空  判断是不是空的
    mp["age"]=20;  //键是age 值是20
    //如果map中没有键,mp["age"]=20;相当于新增

    cout<<mp["age"]<<endl;  //20
    mp["age"]=30;
    cout<<mp["age"]<<endl;  //30    //相当于更新操作
    //map中的键是不允许重复的

    if(mp.find("age")==mp.end()){
        cout<<"没找到,不存在!"<<endl;
    }else{
        cout<<"找到,已经存在!"<<endl;
    }
    //插入操作 pair是个有键值对的模板
    pair<string,int> pair1;
    pair1.first="hello"; //键
    pair1.second=70;    //值

    mp.insert(pair1);
    mp.insert( pair<string,int> ("world",80));

    cout<<mp["hello"]<<endl;  //70


}

 键---值   

#include <iostream>
#include <map>

using namespace std;

int main(){
    map<string,int> mp;
    cout<<mp.empty()<<endl;
    mp["age"]=20;
    cout<<mp["age"]<<endl;
    if(mp.find("age")==mp.end()){
        cout<<"no"<<endl;
    }else{
        cout<<"yes"<<endl;
    }

    pair<string,int> pair1;
    pair1.first="height";
    pair1.second=150;
    mp.insert(pair1);
    cout<<mp["height"]<<endl;
    mp.insert(pair<string,int>("weight",1000));
    //mp.insert(pair<string,int>("height",1000));  //height键已存在 键相同 不允许插入成功
    cout<<mp["weight"]<<endl;
}

3.迭代器

------>[遍历]

迭代器是个特殊的指针。通用的形式访问各种容器;iteratro 可读可写 const iterator 可读

通常使用迭代的方式遍历容器,效率比较高

#include <iostream>
#include <map>
#include <vector>
#include <list>

using namespace std;

int main(){

    map<string,int> mp;
    mp.insert(pair<string,int>("weight",1000));
    mp.insert(pair<string,int>("height",1900));
    mp.insert(pair<string,int>("age",20));

    map<string,int>::iterator it;

    for(it=mp.begin(); it!=mp.end() ; it++){
        cout<<it->first<<" "<<it->second<<endl;
    }

    cout<<"----------------------------"<<endl;

    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    v.push_back(5);

    vector<int>::const_iterator it2;

    for(it2=v.begin();it2!=v.end();it2++){
        cout<<*it2<<" ";
        //++*it2;  //只读迭代器 只允许读取
    }cout<<endl;

    cout<<"----------------------------"<<endl;

    list<string> lis;
    lis.push_back("Tom");
    lis.push_back("Jerry");
    lis.push_back("link&co");
    lis.push_back("BMW");

    list<string>::iterator it3;

    for(it3=lis.begin();it3!=lis.end();it3++){
        cout<<*it3<<endl;
    }cout<<endl;
}

4.继承

(面向对象三大特征:封装 继承 多态)

定义:从已有的类的继承上,创建新的类,会拥有已有类的属性和方法,通常会再此继承上添加新的属性和方法,完成扩充

已存在的类 成为基类 或者 父类

新的类 成为派生类 或者 子类

#include <iostream>
#include <map>
#include <vector>
#include <list>

using namespace std;
class Father{
public:
    string name = "wang";
    void work(){
        cout<<"share"<<endl;
    }
    void show(){
        cout<<"name: "<<name<<endl;
    }
};
class Son:public Father{

};

int main(){

    Son s;
    s.show();
    s.work();
}

 派生类可自己再定义一些属性

如果子类中给出了父类同名的函数,会把父类的同名函数隐藏起来

#include <iostream>
using namespace std;
class Father{
public:
    string first_name="王";
    void work(){
        cout<<"我是一名理发师"<<endl;
    }
    void show(){
        cout<<"姓氏:"<<first_name<<endl;
    }
};
class Son:public Father{
public:
    int age=20;
    void work(){
      cout<<"我是一名老师"<<endl;
    }
    void play_game(){
        cout<<"玩游戏"<<endl;
    }
};

int main(){
    Son s;
    s.work(); 
    s.play_game(); 
    cout<<s.first_name<<" "<<s.age<<endl;
}

调用父类隐藏的函数需要 父类::函数名 的方式访问

#include <iostream>
#include <map> //写明头文件
#include <vector>
#include <list>
using namespace std;
class Father{
public:
string first_name="王";
void work(){
cout<<"我是一名理发师"<<endl;
}
void show(){
cout<<"姓氏:"<<first_name<<endl;
}
};
class Son:public Father{
public:
    int age=20;
void work(){
    cout<<"我是一名老师"<<endl;
}
void show(){
    Father::show();
    cout<<"年龄:"<<age<<endl;
}


};
int main()
{
    Son s;
    s.work(); //隐藏了父类的同名函数,子类直接调用只会打印子类中的函数
    s.Father::work(); //父类::
    s.show();
}

继承的注意事项:

父类的构造函数不会继承下来

子类一定要最直接或间接调用父类的构造函数,来完成父类继承过来数据的初始化,如果子类不写明如何调用父类的构造函数,这时会调用父类无参的构造函数。如果父类没有无参的构造函数,这是会报错

如下:会报错的!

#include <iostream>
using namespace std;
class Father{
private:
    string first_name;
public:
    Father(string s)
    {
        first_name=s;
    }
    void show(){
        cout<<"姓氏:"<<first_name<<endl;
    }
};
class Son:public Father{

};
int main()
{
    Son s;
}

E:\qtfile\helloworld\main.cpp:21: error: use of deleted function 'Son::Son()'
     Son s;
         ^

4.1继承中的构造函数

透传函数

直接调用父类的构造函数,称为透传构造

#include <iostream>
using namespace std;
class Father{
private:
    string first_name;
    int age;
public:
    Father(string s){
        first_name=s;
    }
    Father(string first_name,int age){
        this->first_name=first_name;
        this->age=age;
    }
    void getFirstname(){
        cout<<"姓氏:"<<first_name<<endl;
    }
    void show(){
        cout<<"姓氏:"<<first_name<<"年龄:"<<age<<endl;
    }
};
class Son:public Father{
private:
    int height;   //子类新增的
public:
    Son(string name,int age):Father(name,age){}
    Son(string name, int age,int height):Father(name,age){
        this->height=height; //子类新增的属性,自己完成初始化
    }
    void son_show(){
        Father::show();
        cout<<"身高:"<<height<<endl;
    }

};
int main(){
    Son s("小红",20);
    s.show();

    Son s2("小米",20,167);
    s2.son_show();

}

委托构造

间接的调用父类的构造函数,子类的构造函数调用子类另一个构造函数,另一个构造函数调用了父类的构造函数,相当于间接调用父类的构造函数

 

#include <iostream>
using namespace std;
class Father{
private:
    string first_name;
    int age;
public:
    Father(string s){
        first_name=s;
    }
    Father(string first_name,int age){
        this->first_name=first_name;
        this->age=age;
    }
    void getFirstname(){
        cout<<"姓氏:"<<first_name<<endl;
    }
    void show(){
        cout<<"姓氏:"<<first_name<<"年龄:"<<age<<endl;
    }
};
class Son:public Father{
private:
    int height;   //子类新增的
public:
    Son(string name):Son(name,18){}
    Son(string name,int age):Father(name,age){}
    Son(string name, int age,int height):Father(name,age){
        this->height=height; //子类新增的属性,自己完成初始化
    }
    void son_show(){
        Father::show();
        cout<<"身高:"<<height<<endl;
    }

};
int main(){
    //Son s("小名",20);
    //s.show();

    //Son s2("小米",20,167);
    //s2.son_show();

    Son s3("张飞");
    s3.show();      //姓氏:张飞 年龄:18

}

练习:

封装Person 类

name,age,sex

给出show方法要输出上面三条信息

封装Employee 职员 继承自Person

salary, work_id

给出show方法要输出除了Person类中基本的情况之外 再输出salary, work_id

封装Manager 管理者 继承自Employee

position 职位

给出show方法要输出除了Employee类中基本的情况之外 再输出position

我的方法:

#include <iostream>

using namespace std;
class Person{
private:
    string name;
    string sex;
public:
    Person(string n,string s):name(n),sex(s){}
    void show(){
        cout<<"姓名:"<<name<<endl;
        cout<<"性别:"<<sex<<endl;
    }
};
class Employee:public Person{
private:
    double salary;
    int work_id;
public:
    Employee(string name,string sex,double salary,int work_id):Person(name,sex){
        this->salary=salary;
        this->work_id=work_id;
    }
    void Eshow(){
        Person::show();
        cout<<"薪水:"<<salary<<endl;
        cout<<"工号:"<<work_id<<endl;
    }
};

class Manager:public Employee{
private:
    string position;
public:
    Manager(string name,string sex,double salary,int work_id,string position):Employee(name,sex,salary,work_id){
        this->position=position;
    }
    void Mshow(){
        Employee::Eshow();
        cout<<"职位:"<<position<<endl;
    }
};

int main(){
    Person p1("jerry","男");
    p1.show();
    cout<<"************************"<<endl;
    Employee p2("tom","男",3000.4,22121);
    p2.Eshow();
    cout<<"************************"<<endl;
    Manager p3("lisa","女",6000.5,21233,"HR");
    p3.Mshow();
}

运行结果:

5.权限

public           在本类中可以访问    在子类中可以访问        全局中可以使用          //父亲

protected     在本类中可以访问    在子类中可以访问         全局中不可以使用      //儿子

private         在本类中可以访问    在子类中不可以访问      全局中不可以使用      //外人

 

#include <iostream>

using namespace std;

class Father{
public:
    string first_name="王";
protected:
    string car="link&co";
private:
    string password="123456#";
public:
    void show(){
        cout<<first_name<<endl;
        cout<<car<<endl;
        cout<<password<<endl;
    }
};

class Son:public Father{
public:
    void s_show(){
        cout<<first_name<<endl;
        cout<<car<<endl;
        //cout<<password<<endl;  父类私有的 子类中不可以访问
    }
};

int main(){
   Father f;
   f.show();
   cout<<"*************"<<endl;
   Son s;
   s.s_show();
   cout<<"*************"<<endl;
   //全局相当于外人
   cout<<f.first_name<<endl;
   //cout<<car<<endl;      //保护权限数据在全局中不能访问
   //cout<<password<<endl; //私有内容在全局中不能访问


}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值