c++primer 12.1-12.9

2019-05-27  本文已影响0人  青吟乐

12.1
b1有四个长度
b2在push之后也有四个元素但是在代码块结束后它被析构了
12.2

#ifndef STRBLOB_H_INCLUDED
#define STRBLOB_H_INCLUDED
#include<vector>
#include<memory>
using namespace std;
class StrBlob{
public:
    typedef vector<string>::size_type size_type;
    StrBlob();
    StrBlob(initializer_list<string> il);
    size_type size() const{
        return data->size();
    }
    bool empty(){
        return data->empty();
    }
    //添加删除元素
    void push_back(const string &t){
        data->push_back(t);
    }
    void pop_back();

    //访问元素
    string & front();
    const string & front ()const;
    string & back();
    const string & back ()const;
private:
    shared_ptr<vector<string>> data;
    //如果data[i]不合法,抛出一个异常
    void check(size_type i,const string &msg) const;

};
//无参数构造函数
StrBlob::StrBlob():data(make_shared<vector<string>>()){}
StrBlob::StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){};

//检查容器内元素是否存在的方法
void StrBlob::check(size_type i,const string &msg)const{
    if(i>>=data->size()){
        throw out_of_range(msg);
    }
}

//访问元素的方法
string & StrBlob::front(){
    //如果vector为空,check将会抛出异常
    check(0,"front on empty Str");
    return data->front();
}
const string & StrBlob::front ()const{
    check(0,"front on empty Str");
    return data->front();
}

string & StrBlob::back(){
    check(0,"back on empty Str");
    return data->back();
}
const string & StrBlob::back ()const{
    check(0,"back on empty Str");
    return data->back();
}
void StrBlob::pop_back(){
    check(0,"pop_back on empty Str");
    data->pop_back();
}

12.3
不需要,const版本函数会改变对象属性,但是push_back 和pop_back 就是用来修改对象的,所以不能用const去修饰
12.4
size_type是未定义的无符号数,没有符号,若是给一个负数,它会自动转化成一个正数
12.5
接受默认转化,优点是较为方便
缺点是有时候可能用到initialzer_list但是它被当做参数转化成了类的对象

12.6
首先是头文件放了三个放方法,注意动态指针作为参数向方法传递的时候都带*,智能指针不需要

#ifndef FUNCTION_H_INCLUDED
#define FUNCTION_H_INCLUDED
#include<vector>
#include<list>
#include<fstream>
using namespace std;
//获取动态vector<int>指针
vector<int>* Get(){
     return new vector<int>;
}


//输入方法 注意这里ifstream 要使用引用对象
void   Input(vector<int> *p , ifstream &ifs){
    int i;
    while(ifs>>i){
        p->push_back(i);
    }
}


//展示方法使用c++11标准遍历即可
void show(vector<int> *p){
    for(auto c:*p){
        cout<<c<<" ";
    }
    cout<<endl;
}
#endif // FUNCTION_H_INCLUDED

main函数

#include <iostream>
#include<vector>
#include<fstream>
#include"function.h"
#include<memory>
using namespace std;

 int main()
 {
    ifstream in1("C:\\study\\c++test\\number.txt");
    auto p = Get();
    Input(p,in1);
    show(p);
    delete p;
    return 0;

 }

12.7
12.6的函数的智能指针版本,注意智能指针参数前不加*,make_shared方法后跟的是<>

#include <iostream>
#include<vector>
#include<fstream>
#include"function.h"
#include<memory>
using namespace std;

//智能指针版本的三个函数
//返回一个vector<int>的指针

shared_ptr<vector<int >> Sget(){
    return make_shared<vector<int>>();
}
//赋值函数
void Sinput(shared_ptr<vector<int >> p,ifstream &ifs){
    int i;
    while(ifs>>i){
        p->push_back(i);
    }
}
//遍历函数
void Sshow(shared_ptr<vector<int>> p){
    for(auto c:*p){
        cout<<c<<" ";
    }
    cout<<endl;
}
 int main()
 {
    ifstream in2("C:\\study\\c++test\\number.txt");
    auto q=Sget();
    Sinput(q,in2);
    Sshow(q);
    return 0;
 }

12.8
编译不会出错,但是要注意在b外面将内存释放
12.9
q和r是动态指针,都指向存放42的那块内存,但是因为存放100的那块内存没有被释放并且没有被引用,就发生了内存泄漏
r2,q2是智能指针,都指向42的那块内存,由于存放100的那块内存没有被引用,所以它被自动释放

上一篇 下一篇

猜你喜欢

热点阅读