当前位置: 首页 > news >正文

c++ primer中文版第五版作业第十八章

仓库地址

文章目录

      • 18.1
      • 18.2
      • 18.3
      • 18.4
      • 18.5
      • 18.6
      • 18.7
      • 18.8
      • 18.9
      • 18.10
      • 18.11
      • 18.12
      • 18.13
      • 18.14
      • 18.15
      • 18.16
        • 位置一
          • using声明
        • 位置二
          • using声明
        • 位置一
          • using指示
        • 位置二
          • using指示
      • 18.17
      • 18.18
      • 18.19
      • 18.20
      • 18.21
      • 18.22
      • 18.23
      • 18.24
      • 18.25
      • 18.26
      • 18.26
      • 18.28
      • 18.29
      • 18.30

18.1

  1. 此时r是一个range_error类型的局部对象
  2. 此时p是exception类型的指针,指向局部对象r
    如果throw p就会抛出一个指向局部对象的指针,那么有可能在执行catch语句之前,该局部对象已经被销毁。

18.2

 v和in可以调用其析构函数释放资源,而p无法正确释放资源,导致内存泄漏。

18.3

  1. 使用智能指针管理p
    unique_ptr<int []> p(new int[v.size()])
  2. 使用类来控制资源的分配
class ptr
{public:explicit ptr(size_t len):p(new int[len]) {}ptr(const ptr&)=delete;ptr & operator=(const ptr&)=delete;~ptr(){delete [] p;}private:int *p;
};

18.4

catch语句是按照其出现的顺序逐一进行匹配的,所以根据继承体系catch(exception)后面的catch子句永远无法被匹配到。

try{
//
}catch(overflow_error eobj){
//
}catch(const runtime_error &re){
//
}catch(exception){/**/}

18.5

#include <iostream>
#include <exception>
#include <stdexcept>
#include <cstdlib>
int main(){try{//使用c++标准库
}catch(const exception &e){std::cout<<e.what()<<std::endl;abort();
}
}

18.6

  1. throw exceptionType * eobj,注意不能抛出一个指向局部对象的指针
  2. 抛出的所有异常都能被捕获
  3. int a=1;throw a;抛出的所有int类型值都能被捕获,但是其余的整型类型无法进行算数类型转换为int。

18.7

#ifndef BLOB_H
#define BLOB_H
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <string>
#include <initializer_list>
#include <stdexcept>
template <typename> class BlobPtr;
template <typename> class Blob;
//Blob
template <typename T> bool operator==(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator!=(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator<(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator<=(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator>(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator>=(const Blob<T> &,const Blob<T> &);
template <typename T> class Blob
{friend class BlobPtr<T>;friend bool operator==<T>(const Blob<T> &,const Blob<T> &);friend bool operator!=<T>(const Blob<T> &,const Blob<T> &);friend bool operator< <T>(const Blob<T> &,const Blob<T> &);friend bool operator<= <T>(const Blob<T> &,const Blob<T> &);friend bool operator> <T>(const Blob<T> &,const Blob<T> &);friend bool operator>= <T>(const Blob<T> &,const Blob<T> &);public:typedef T value_type;typedef typename std::vector<T>::size_type size_type;Blob() try:data(std::make_shared<std::vector<T>>()){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}Blob(std::initializer_list<T> il) try:data(std::make_shared<std::vector<T>>(il)){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}Blob(const Blob &org) try:data(std::make_shared<std::vector<T>>(*org.data)){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}template <typename it> Blob(it b,it e) try:data(std::make_shared<std::vector<T>>(b,e)) {} catch(std::bad_alloc &ba){std::cout<<ba.what()<<std::endl;}Blob &operator=(const Blob &);T & operator[](size_type i);const T & operator[](size_type i) const;size_type size() const {return data->size();}bool empty() const {return data->empty;}void push_back(const T &t){data->push_back(t);}void push_back(T &&t){data->push_back(std::move(t));}void pop_back();T & front();T & back();const T & front() const;const T & back() const;BlobPtr<T> begin();BlobPtr<T> end();private:std::shared_ptr<std::vector<T>> data;void check(size_type i,const std::string &msg) const;
};
//BlobPtr
template <typename T> bool operator==(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator!=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator<(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator<=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator>(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator>=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> class BlobPtr
{friend bool operator==<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator!=<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator< <T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator<=<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator><T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator>=<T>(const BlobPtr<T> &,const BlobPtr<T> &);public:typedef typename std::vector<T>::size_type size_type;BlobPtr():curr(0){}BlobPtr(const Blob<T> &blob,size_type sz=0):wptr(blob.data),curr(sz){}T & operator[](size_type i);const T & operator[](size_type i) const;BlobPtr & operator++();BlobPtr & operator++(int);BlobPtr & operator--();BlobPtr & operator--(int);BlobPtr operator+(size_type) const;BlobPtr operator-(size_type) const;BlobPtr operator+=(size_type) const;BlobPtr operator-=(size_type) const;T & operator*() const;T * operator->() const;private:std::shared_ptr<std::vector<T>> check(size_type i,const std::string &msg) const;std::weak_ptr<std::vector<T>> wptr;size_type curr=0;
};
//Blob
template <typename T> Blob<T> & Blob<T>::operator=(const Blob &rhs)
{data=std::make_shared<std::vector<T>>(*rhs.data);return *this;
}
template <typename T> T & Blob<T>::operator[](size_type i)
{check(i,"subscript out of range");return (*data)[i];
}
template <typename T> const T & Blob<T>::operator[](size_type i) const
{check(i,"subscript out of range");return (*data)[i];
}
template <typename T> void Blob<T>::pop_back()
{check(0,"pop_back on empty Blob");data->pop_back();
}
template <typename T> T & Blob<T>::front()
{check(0,"front on empty Blob");return data->front();
}
template <typename T> const T & Blob<T>::front() const
{check(0,"front on empty Blob");return data->front();
}
template <typename T> T & Blob<T>::back()
{check(0,"back on empty Blob");return data->back();
}
template <typename T> const T & Blob<T>::back() const
{check(0,"back on empty Blob");return data->back();
}
template <typename T> BlobPtr<T> Blob<T>::begin()
{return BlobPtr<T>(*this);
}
template <typename T> BlobPtr<T> Blob<T>::end()
{return BlobPtr<T>(*this,data->size());
}
template <typename T> inline void Blob<T>::check(size_type i,const std::string &msg) const
{if(i>=data->size())throw std::out_of_range(msg);
}
template <typename T> bool operator==(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data==*rhs.data;
}
template <typename T> bool operator!=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs==rhs);
}
template <typename T> bool operator<(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data<*rhs.data;
}
template <typename T> bool operator<=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs>rhs);
}
template <typename T> bool operator>(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data>*rhs.data;
}
template <typename T> bool operator>=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs<rhs);
}
//BlobPtr
template <typename T> std::shared_ptr<std::vector<T>> BlobPtr<T>::check(size_type i,const std::string &msg) const
{auto ret=wptr.lock();if(!ret)throw std::runtime_error("unbound BlobPtr");if(i>=ret->size())throw std::out_of_range(msg);return ret;
}
template <typename T> T & BlobPtr<T>::operator[](size_type i)
{auto ret=check(i,"index out of range");return (*ret)[i];
}
template <typename T> const T & BlobPtr<T>::operator[](size_type i) const
{auto ret=check(i,"index out of range");return (*ret)[i];
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator++()
{check(curr,"increment past end of BlobPtr");++curr;return *this;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator++(int)
{BlobPtr ret=*this;++*this;return ret;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator--()
{--curr;check(curr,"decrement past the begin of BlobPtr");return *this;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator--(int)
{BlobPtr ret=*this;--*this;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator+(size_type i) const
{BlobPtr ret(*this);ret+=i;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator-(size_type i) const
{BlobPtr ret(*this);ret-=i;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator+=(size_type i) const
{check(curr+i,"increment past end of range");while(--i)++*this;return *this;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator-=(size_type i) const
{check(curr-i,"decrement past begin of range");while(--i)--*this;return *this;
}
template <typename T> T & BlobPtr<T>::operator*() const
{auto p=check(curr,"dereference past end");return (*p)[curr];
}
template <typename T> T * BlobPtr<T>::operator->() const
{return & this->operator*();
}
template <typename T> bool operator==(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{auto l=lhs.wptr.lock();auto r=rhs.wptr.lock();if(l==r)return (!r||lhs.curr==rhs.curr);elsereturn false;
}
template <typename T> bool operator!=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs==rhs);
}
template <typename T> bool operator<(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{auto l=lhs.wptr.lock();auto r=rhs.wptr.lock();if(l==r&&l)return lhs.curr<rhs.curr;elsereturn false;
}
template <typename T> bool operator<=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs>rhs);
}
template <typename T> bool operator>(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return rhs<lhs;
}
template <typename T> bool operator>=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs<rhs);
}
#endif

18.8

#ifndef BLOB_H
#define BLOB_H
#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <string>
#include <initializer_list>
#include <stdexcept>
template <typename> class BlobPtr;
template <typename> class Blob;
//Blob
template <typename T> bool operator==(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator!=(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator<(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator<=(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator>(const Blob<T> &,const Blob<T> &);
template <typename T> bool operator>=(const Blob<T> &,const Blob<T> &);
template <typename T> class Blob
{friend class BlobPtr<T>;friend bool operator==<T>(const Blob<T> &,const Blob<T> &);friend bool operator!=<T>(const Blob<T> &,const Blob<T> &);friend bool operator< <T>(const Blob<T> &,const Blob<T> &);friend bool operator<= <T>(const Blob<T> &,const Blob<T> &);friend bool operator> <T>(const Blob<T> &,const Blob<T> &);friend bool operator>= <T>(const Blob<T> &,const Blob<T> &);public:typedef T value_type;typedef typename std::vector<T>::size_type size_type;Blob() noexcept(false) try:data(std::make_shared<std::vector<T>>()){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}Blob(std::initializer_list<T> il) noexcept(false) try:data(std::make_shared<std::vector<T>>(il)){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}Blob(const Blob &org) noexcept(false) try:data(std::make_shared<std::vector<T>>(*org.data)){} catch(std::bad_alloc &e){std::cout<<e.what()<<std::endl;}template <typename it> Blob(it b,it e) noexcept(false) try:data(std::make_shared<std::vector<T>>(b,e)) {} catch(std::bad_alloc &ba){std::cout<<ba.what()<<std::endl;}Blob &operator=(const Blob &);T & operator[](size_type i);const T & operator[](size_type i) const;size_type size() const {return data->size();}bool empty() const {return data->empty;}void push_back(const T &t){data->push_back(t);}void push_back(T &&t){data->push_back(std::move(t));}void pop_back();T & front();T & back();const T & front() const;const T & back() const;BlobPtr<T> begin();BlobPtr<T> end();~Blob() noexcept {};private:std::shared_ptr<std::vector<T>> data;void check(size_type i,const std::string &msg) const;
};
//BlobPtr
template <typename T> bool operator==(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator!=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator<(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator<=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator>(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> bool operator>=(const BlobPtr<T> &,const BlobPtr<T> &);
template <typename T> class BlobPtr
{friend bool operator==<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator!=<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator< <T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator<=<T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator><T>(const BlobPtr<T> &,const BlobPtr<T> &);friend bool operator>=<T>(const BlobPtr<T> &,const BlobPtr<T> &);public:typedef typename std::vector<T>::size_type size_type;BlobPtr():curr(0){}BlobPtr(const Blob<T> &blob,size_type sz=0):wptr(blob.data),curr(sz){}T & operator[](size_type i);const T & operator[](size_type i) const;BlobPtr & operator++();BlobPtr & operator++(int);BlobPtr & operator--();BlobPtr & operator--(int);BlobPtr operator+(size_type) const;BlobPtr operator-(size_type) const;BlobPtr operator+=(size_type) const;BlobPtr operator-=(size_type) const;T & operator*() const;T * operator->() const;private:std::shared_ptr<std::vector<T>> check(size_type i,const std::string &msg) const;std::weak_ptr<std::vector<T>> wptr;size_type curr=0;
};
//Blob
template <typename T> Blob<T> & Blob<T>::operator=(const Blob &rhs)
{data=std::make_shared<std::vector<T>>(*rhs.data);return *this;
}
template <typename T> T & Blob<T>::operator[](size_type i)
{check(i,"subscript out of range");return (*data)[i];
}
template <typename T> const T & Blob<T>::operator[](size_type i) const
{check(i,"subscript out of range");return (*data)[i];
}
template <typename T> void Blob<T>::pop_back()
{check(0,"pop_back on empty Blob");data->pop_back();
}
template <typename T> T & Blob<T>::front()
{check(0,"front on empty Blob");return data->front();
}
template <typename T> const T & Blob<T>::front() const
{check(0,"front on empty Blob");return data->front();
}
template <typename T> T & Blob<T>::back()
{check(0,"back on empty Blob");return data->back();
}
template <typename T> const T & Blob<T>::back() const
{check(0,"back on empty Blob");return data->back();
}
template <typename T> BlobPtr<T> Blob<T>::begin()
{return BlobPtr<T>(*this);
}
template <typename T> BlobPtr<T> Blob<T>::end()
{return BlobPtr<T>(*this,data->size());
}
template <typename T> inline void Blob<T>::check(size_type i,const std::string &msg) const
{if(i>=data->size())throw std::out_of_range(msg);
}
template <typename T> bool operator==(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data==*rhs.data;
}
template <typename T> bool operator!=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs==rhs);
}
template <typename T> bool operator<(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data<*rhs.data;
}
template <typename T> bool operator<=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs>rhs);
}
template <typename T> bool operator>(const Blob<T> &lhs,const Blob<T> &rhs)
{return *lhs.data>*rhs.data;
}
template <typename T> bool operator>=(const Blob<T> &lhs,const Blob<T> &rhs)
{return !(lhs<rhs);
}
//BlobPtr
template <typename T> std::shared_ptr<std::vector<T>> BlobPtr<T>::check(size_type i,const std::string &msg) const
{auto ret=wptr.lock();if(!ret)throw std::runtime_error("unbound BlobPtr");if(i>=ret->size())throw std::out_of_range(msg);return ret;
}
template <typename T> T & BlobPtr<T>::operator[](size_type i)
{auto ret=check(i,"index out of range");return (*ret)[i];
}
template <typename T> const T & BlobPtr<T>::operator[](size_type i) const
{auto ret=check(i,"index out of range");return (*ret)[i];
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator++()
{check(curr,"increment past end of BlobPtr");++curr;return *this;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator++(int)
{BlobPtr ret=*this;++*this;return ret;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator--()
{--curr;check(curr,"decrement past the begin of BlobPtr");return *this;
}
template <typename T> BlobPtr<T> & BlobPtr<T>::operator--(int)
{BlobPtr ret=*this;--*this;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator+(size_type i) const
{BlobPtr ret(*this);ret+=i;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator-(size_type i) const
{BlobPtr ret(*this);ret-=i;return ret;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator+=(size_type i) const
{check(curr+i,"increment past end of range");while(--i)++*this;return *this;
}
template <typename T> BlobPtr<T> BlobPtr<T>::operator-=(size_type i) const
{check(curr-i,"decrement past begin of range");while(--i)--*this;return *this;
}
template <typename T> T & BlobPtr<T>::operator*() const
{auto p=check(curr,"dereference past end");return (*p)[curr];
}
template <typename T> T * BlobPtr<T>::operator->() const
{return & this->operator*();
}
template <typename T> bool operator==(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{auto l=lhs.wptr.lock();auto r=rhs.wptr.lock();if(l==r)return (!r||lhs.curr==rhs.curr);elsereturn false;
}
template <typename T> bool operator!=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs==rhs);
}
template <typename T> bool operator<(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{auto l=lhs.wptr.lock();auto r=rhs.wptr.lock();if(l==r&&l)return lhs.curr<rhs.curr;elsereturn false;
}
template <typename T> bool operator<=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs>rhs);
}
template <typename T> bool operator>(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return rhs<lhs;
}
template <typename T> bool operator>=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{return !(lhs<rhs);
}
#endif

18.9

Sales_data.h

#include <iostream>
#include <string>
#include <stdexcept>
class isbn_mismatch: public std::logic_error
{
public:explicit isbn_mismatch(const std::string &s):std::logic_error(s) {}isbn_mismatch(const std::string &s,const std::string &lhs,const std::string &rhs):std::logic_error(s),left(lhs),right(rhs) {}const std::string left,right;
};
class Sales_data
{friend std::istream & operator>>(std::istream &,Sales_data &);friend std::ostream & operator<<(std::ostream &,const Sales_data &);friend Sales_data operator+(const Sales_data &,const Sales_data &);public:std::string isbn() const {return bookNo;}Sales_data()=default;Sales_data(const std::string &s):bookNo(s) {}Sales_data(const std::string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(n*p) {}Sales_data & operator+=(const Sales_data &);operator std::string() const {return bookNo;}operator double() const {return revenue;}private:std::string bookNo;unsigned units_sold=0;double revenue=0.0;double avg_price() const;
};
std::istream & operator>>(std::istream &,Sales_data &);
std::ostream & operator<<(std::ostream &,const Sales_data &);
Sales_data operator+(const Sales_data &,const Sales_data &);
bool compareIsbn(const Sales_data &lhs,const Sales_data &rhs);

Sales_data.cpp

#include "Sales_data.h"
inline double Sales_data::avg_price() const
{if(units_sold)return revenue/units_sold;elsereturn 0;
}
std::istream & operator>>(std::istream &is,Sales_data &src)
{double price=0.0;is>>src.bookNo>>src.units_sold>>price;if(is)src.revenue=src.units_sold*price;elsesrc=Sales_data();return is;
}
std::ostream & operator<<(std::ostream &os,const Sales_data &src)
{os<<src.isbn()<<" "<<src.units_sold<<" "<<src.revenue<<" "<<src.avg_price();return os;
}
Sales_data & Sales_data::operator+=(const Sales_data & rhs)
{*this=*(this)+rhs;return *this;
}
Sales_data operator+(const Sales_data &lhs,const Sales_data &rhs)
{Sales_data tmp;if(lhs.isbn()!=rhs.isbn())throw isbn_mismatch("wrong isbns!",lhs.isbn(),rhs.isbn());tmp.bookNo=lhs.bookNo;tmp.units_sold=lhs.units_sold+rhs.units_sold;tmp.revenue=lhs.revenue+rhs.revenue;return tmp;
}
bool compareIsbn(const Sales_data &lhs,const Sales_data &rhs)
{return lhs.isbn()<rhs.isbn();
}

test1.cpp

#include <iostream>
#include "Sales_data.h"
int main(void)
{Sales_data a("111",2,30),b("112",3,50);a+b;return  0;
}

不处理异常的输出
terminate called after throwing an instance of ‘isbn_mismatch’
what(): wrong isbns!
Aborted
test2.cpp

#include <iostream>
#include "Sales_data.h"
int main(void)
{Sales_data a("111",2,30),b("112",3,50);try{a+b;}catch(const isbn_mismatch &e){std::cerr<<e.what()<<": left isbn ("<<e.left<<") right isbn ("<<e.right<<")"<<std::endl;}return  0;
}

处理异常的输出
wrong isbns!: left isbn (111) right isbn (112)

18.10

见18.9

18.11

 如果what函数抛出异常的话,没有对应的catch子句捕获处理,就会调用terminate使程序结束,破坏正常逻辑。

18.12

Query.h

#ifndef _QUERY_H
#define _QUERY_H
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include <fstream>
namespace chapter15
{class QueryResult;class TextQuery{public:using line_no=std::vector<std::string>::size_type;TextQuery(std::ifstream &);QueryResult query(const std::string &) const;private:std::shared_ptr<std::vector<std::string>> file;std::map<std::string,std::shared_ptr<std::set<line_no>>> wm;};class QueryResult{friend std::ostream &print(std::ostream &,const QueryResult &);public:QueryResult(std::string s,std::shared_ptr<std::set<std::vector<std::string>::size_type>> l,std::shared_ptr<std::vector<std::string>> f):sought(s),lines(l),file(f){}std::set<std::vector<std::string>::size_type>::iterator begin() const {return lines->begin();}std::set<std::vector<std::string>::size_type>::iterator end() const {return lines->end();}std::shared_ptr<std::vector<std::string>> get_file(){return file;}private:std::string sought;std::shared_ptr<std::set<std::vector<std::string>::size_type>> lines;std::shared_ptr<std::vector<std::string>> file;};std::ostream &print(std::ostream &,const QueryResult &);inline std::string make_plural(std::size_t count,const std::string &word,const std::string &ending){return (count>1)?word+ending:word;}class Query_base{friend class Query;protected:using line_no=TextQuery::line_no;virtual ~Query_base()=default;private:virtual QueryResult eval(const TextQuery &) const=0;virtual std::string rep() const=0;};class Query{friend Query operator~(const Query &);friend Query operator&(const Query &,const Query &);friend Query operator|(const Query &,const Query &);public:Query(const std::string &);QueryResult eval(const TextQuery &t) const {return q->eval(t);}std::string rep() const {return q->rep();}private:Query(std::shared_ptr<Query_base> query):q(query) {}std::shared_ptr<Query_base> q;};class WordQuery:public Query_base{friend class Query;private:WordQuery(const std::string &s):query_word(s) {}virtual QueryResult eval(const TextQuery &t) const {return t.query(query_word);}virtual std::string rep() const {return query_word;}std::string query_word;};inline Query::Query(const std::string &s):q(new WordQuery(s)) {}class NotQuery:public Query_base{friend Query operator~(const Query &);private:NotQuery(const Query &q):query(q) {}virtual QueryResult eval(const TextQuery &) const;virtual std::string rep() const {return "~("+query.rep()+")";}Query query;};inline Query operator~(const Query &q) {return std::shared_ptr<Query_base>(new NotQuery(q));}class BinaryQuery:public Query_base{protected:BinaryQuery(const Query &left,const Query &right,const std::string &s):lhs(left),rhs(right),opSym(s) {}virtual std::string rep() const {return "("+lhs.rep()+" "+opSym+" "+rhs.rep()+")";}Query lhs,rhs;std::string opSym;};class AndQuery:public BinaryQuery{friend Query operator&(const Query&,const Query&);private:AndQuery(const Query &left,const Query &right):BinaryQuery(left,right,"&") {}virtual QueryResult eval(const TextQuery &) const;};inline Query operator&(const Query &left,const Query &right) {return std::shared_ptr<Query_base>(new AndQuery(left,right));}class OrQuery:public BinaryQuery{friend Query operator|(const Query &,const Query &);private:OrQuery(const Query &left,const Query &right):BinaryQuery(left,right,"|") {}virtual QueryResult eval(const TextQuery &) const;};inline Query operator|(const Query &left,const Query &right) {return std::shared_ptr<Query_base>(new OrQuery(left,right));}inline std::ostream & operator<<(std::ostream &os,const Query &q) {return os<<q.rep();}
}
#endif

Query.cpp

#include <sstream>
#include <algorithm>
#include <cctype>
#include "Query.h"
namespace chapter15
{TextQuery::TextQuery(std::ifstream &infile):file(new std::vector<std::string>){std::string text;while(getline(infile,text)){file->push_back(text);std::size_t line_number=file->size()-1;std::istringstream line(text);std::string word;while(line>>word){std::string key_word;for(auto c:word){if(!ispunct(c))key_word+=c;}std::shared_ptr<std::set<line_no>> &lines=wm[key_word];if(!lines)lines.reset(new std::set<line_no>);lines->insert(line_number);}}}QueryResult TextQuery::query(const std::string &sought) const{static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>);std::map<std::string,std::shared_ptr<std::set<line_no>>>::const_iterator map_it=wm.find(sought);if(map_it==wm.end())return QueryResult(sought,nodata,file);elsereturn QueryResult(sought,map_it->second,file);}std::ostream &print(std::ostream &os,const QueryResult &qr){os<<"Executing Query for: "<<qr.sought<<std::endl;os<<qr.sought<<" occurs "<<qr.lines->size()<<" "<<make_plural(qr.lines->size(),"time","s")<<std::endl;for(auto num:*(qr.lines))os<<"\t(line "<<num+1<<") "<<*(qr.file->begin()+num)<<std::endl;return os;}QueryResult NotQuery::eval(const TextQuery &text) const{auto result=query.eval(text);auto beg=result.begin(),end=result.end();auto ret_lines=std::make_shared<std::set<line_no>>();auto sz=result.get_file()->size();for(std::size_t n=0;n!=sz;++n){if(beg==end||*beg!=n)ret_lines->insert(n);else if(beg!=end)++beg;}return QueryResult(rep(),ret_lines,result.get_file());}QueryResult OrQuery::eval(const TextQuery &text) const{auto left=lhs.eval(text),right=rhs.eval(text);auto ret_lines=std::make_shared<std::set<line_no>>(left.begin(),left.end());ret_lines->insert(right.begin(),right.end());return QueryResult(rep(),ret_lines,left.get_file());}QueryResult AndQuery::eval(const TextQuery &text) const{auto left=lhs.eval(text),right=rhs.eval(text);auto ret_lines=std::make_shared<std::set<line_no>>();set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(*ret_lines,ret_lines->begin()));return QueryResult(rep(),ret_lines,left.get_file());}
}

TextQuery.h

#ifndef TEXT_QUERY_H
#define TEXT_QUERY_H
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include <fstream>
#include <tuple>
namespace chapter10
{class TextQuery{public:using line_no=std::vector<std::string>::size_type;TextQuery(std::ifstream &);std::tuple<std::string,std::shared_ptr<std::set<std::vector<std::string>::size_type>>,std::shared_ptr<std::vector<std::string>>> query(const std::string &) const;private:std::shared_ptr<std::vector<std::string>> file;std::map<std::string,std::shared_ptr<std::set<line_no>>> wm;};inline std::string make_plural(std::size_t count,const std::string &word,const std::string &ending){return (count>1)?word+ending:word;}std::ostream &print(std::ostream &,const std::tuple<std::string,std::shared_ptr<std::set<std::vector<std::string>::size_type>>,std::shared_ptr<std::vector<std::string>>> &);
}
#endif

TextQuery.cpp

#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <string>
#include <memory>
#include "TextQuery.h"
using namespace std;
namespace chapter10
{TextQuery::TextQuery(ifstream &infile):file(new vector<string>){string text;while(getline(infile,text)){file->push_back(text);size_t line_number=file->size()-1;istringstream line(text);string word;while(line>>word){shared_ptr<set<line_no>> &lines=wm[word];if(!lines)lines.reset(new set<line_no>);lines->insert(line_number);}}}std::tuple<std::string,std::shared_ptr<std::set<std::vector<std::string>::size_type>>,std::shared_ptr<std::vector<std::string>>> TextQuery::query(const string &sought) const{static shared_ptr<set<line_no>> nodata(new set<line_no>);map<string,shared_ptr<set<line_no>>>::const_iterator map_it=wm.find(sought);if(map_it==wm.end())return tuple(sought,nodata,file);elsereturn tuple(sought,map_it->second,file);}std::ostream &print(std::ostream &os,const std::tuple<std::string,std::shared_ptr<std::set<std::vector<std::string>::size_type>>,std::shared_ptr<std::vector<std::string>>> &tp){os<<std::get<0>(tp)<<" occurs "<<std::get<1>(tp)->size()<<" "<<make_plural(std::get<1>(tp)->size(),"time","s")<<std::endl;for(auto num:*(get<1>(tp)))os<<"\t(line "<<num+1<<")"<<*(get<2>(tp)->begin()+num)<<std::endl;return os;}
}

test.cpp

#include <fstream>
#include "Query.h"
using namespace std;
using chapter15::Query;
using chapter15::TextQuery;
int main(int argc,char *argv[])
{ifstream infile(argv[1]);TextQuery text(infile);Query q=Query("fiery")&Query("bird")|Query("wind");print(cout,q.eval(text));return 0;
}

18.13

 需要使用文件作用域或者命名空间作用域的静态变量时可以使用未命名的命名空间。

18.14

mathLib::MatrixLib::matrix mathLib::MatrixLib::operator*(const matrix &,const matrix &);

18.15

using声明:一次只引入命名空间的一个成员,它的有效范围从using声明的地方开始,到using声音所在作用域结束为止。
using指示:使特定的命名空间中所有的名字都可见,这些名字一般被看作是出现在最近的外层作用域中,如果遇到成员冲突的情况,需要使用作用域运算符指明所需的版本。

18.16

位置一
using声明

ivar成员冲突

位置二
using声明

dvar成员冲突

位置一
using指示

++ivar这句将有二义性错误

位置二
using指示

++ivar这句将有二义性错误

18.17

1

#include <iostream>	
namespace Exercise
{int ivar=0;double dvar=0;const int limit=1000;
}
int ivar=0;using Exercise::ivar;
using Exercise::dvar;
using Exercise::limit;void manip()
{double dvar=3.1416;int iobj=limit+1;++ivar;++::ivar;
}
int main(void)
{return 0;
}

2

#include <iostream>	
namespace Exercise
{int ivar=0;double dvar=0;const int limit=1000;
}
int ivar=0;void manip()
{using Exercise::ivar;
using Exercise::dvar;
using Exercise::limit;double dvar=3.1416;int iobj=limit+1;++ivar;++::ivar;
}
int main(void)
{return 0;
}

3

#include <iostream>	
namespace Exercise
{int ivar=0;double dvar=0;const int limit=1000;
}
int ivar=0;using namespace Exercise;void manip()
{double dvar=3.1416;int iobj=limit+1;++ivar;++::ivar;
}
int main(void)
{return 0;
}

4

#include <iostream>	
namespace Exercise
{int ivar=0;double dvar=0;const int limit=1000;
}
int ivar=0;void manip()
{using namespace Exercise;double dvar=3.1416;int iobj=limit+1;++ivar;++::ivar;
}
int main(void)
{return 0;
}

18.18

 当mem1是一个string时程序因为更特例化的原因,会调用string中定义的swap版本,而int是内置类型,内置类型没有特定版本的swap,所以会调用std::swap。

18.19

 如果使用std::swap的形式,则是直接指明调用std命名空间中的swap版本。

18.20

  • 命名空间primerLib中声明的compte将被加入候选函数集
    候选函数void compute() void compute(const void *) void compute(int) void compute(double,double=3.4) void compute(char*,char*=0)
    可行函数
    void compute(const void *)0能转换成任意指针类型
    void compute(int)精确匹配
    void compute(double,double=3.4)int向double的算术类型转换
    void compute(char*,char*=0)0能转换成任意指针类型
  • 如果将using声明置于f函数中compute的调用点之前,将隐藏全局作用域中声明的compute.
    候选函数void compute() void compute(const void *)
    可行函数
    void compute(const void *)0能转换成任意指针类型

18.21

1 正确,public继承CAD,private继承Vehicle
2 错误,在一个派生列表中重复继承了同一个基类
3 正确,public继承istream,public继承ostream

18.22

 构造函数的执行顺序是A->B->C->X->Y->Z->MI

18.23

都允许

18.24

ZooAnimal *pz=new Panda("ying_yang")
pb->print();//调用Panda::print()
pb->cuddle();//错误,不属于ZooAnimal的接口
pb->highlight();//错误,不属于ZooAnimal的接口
delete->pb;//正确,Panda::~Panda()

18.25

  1. MI::print()
  2. MI::print()
  3. MI::print()
  4. MI::~MI()
  5. MI::~MI()
  6. MI::~MI()

18.26

 因为派生类的名字将隐藏基类的同名成员,所以MI不加前缀限定符的print函数只有接受std::vector参数的版本,而42无法隐式转换为该类型,所以调用失败。
可以这样修改:

struct MI:public Derived,public Base2
{void print(std::vector<double>);void print(int i){Base1::print(i);}protected:int *ival;std::vector<double> dvec;
}

18.26

  1. 所有可见的名字:
函数内:int dval;double cval;
类内:int *ival;std::vector<double> dvec;void print(std::vector<double>);
Derived:void Derived::print(std::string) const;std::string sval;double Derived::dval;
Base1:void Base1::print(int) const;int Base1::ival;double Base1::dval;char Base1::cval;
Base2:void Base2::print(double) const;int Base2::ival;double fval;char Base2::cval;
全局作用域:int ival;double dval;
dval    cval    ival    print都是继承自多个基类。
dval:Derived::dval  Base1::dval
cval:Base1::cval    Base2::cval
ival:Base1::ival    Base2::ival
print:Derived::print    Base1::print    Base2::print
void MI::foo(double cval)
{int dval;dval=Base1::dval+Derived::dval;
}
void MI::foo(double cval)
{int dval;Base2::fval=dvec.back();
}
void MI::foo(double cval)
{int dval;sval[0]=Base1::cval;
}

18.28

无需前缀限定符:
    Derived1::bar
     Derived2::ival
需要前缀限定符:
     Derived1::foo
     Derived2::foo
     Base::bar
     Base::ival
     Derived1::cval
     Derived2::cval

18.29

构造函数顺序:Class() Base() D1() D2() MI() Class() Final()
析构函数顺序:Final() Class() MI() D2() D1() Base() Class()
2. 1个base部分,两个Class部分。
3.
pb=new Class错误,不存在基类指针向派生类的隐式转换
pc=new Final错误,Class接口的使用会导致二义性错误
pmi=pb错误,不存在基类指针向派生类的隐式转换
pd2=pmi正确

18.30

这样定义的话,由于存在歧义,直接基类Class在Final中无法访问
class Class{};
class Base:public Class
{public:Base()=default;Base(const Base &b):i(b.i) {}Base(const int &ri):i(ri) {}private:int i;
};
class D1:public virtual Base
{public:D1()=default;D1(const D1 &d):Base(d) {}D1(const int &ri):Base(ri) {}
};
class D2:public virtual Base
{public:D2()=default;D2(const D2 &d):Base(d) {}D2(const int &ri):Base(ri) {}
};
class MI:public D1,public D2
{public:MI()=default;MI(const MI &mi):Base(mi),D1(mi),D2(mi) {}MI(const int &ri):Base(ri),D1(ri),D2(ri) {}
};
class Final:public MI,public Class
{public:Final()=default;Final(const Final &fi):Base(fi),MI(fi),Class() {}Final(const int &ri):Base(ri),MI(ri),Class() {}
};

相关文章:

c++ primer中文版第五版作业第十八章

仓库地址 文章目录 18.118.218.318.418.518.618.718.818.918.1018.1118.1218.1318.1418.1518.16位置一using声明 位置二using声明 位置一using指示 位置二using指示 18.1718.1818.1918.2018.2118.2218.2318.2418.2518.2618.2618.2818.2918.30 18.1 此时r是一个range_error类型…...

vue触发真实的点击 事件 跟用户行为一致

<template><div><button ref"myButton" click"handleClick">按钮</button></div> </template><script> export default {methods: {handleClick() {const button this.$refs.myButton;// 创建一个鼠标点击事件…...

Java进程CPU高负载排查

Java进程CPU高负载排查步骤_java进程cpu使用率高排查_YouluBank的博客-CSDN博客 【问题定位】使用arthas定位CPU高的问题_arthas cpu高_秋装什么的博客-CSDN博客 CPU飙升可能原因 CPU 上下文切换过多。 对于 CPU 来说&#xff0c;同一时刻下每个 CPU 核心只能运行-个线程&…...

Linux编程4.1 网络编程-前导

1、内容概述 网络的基本概念TCP/IP协议概述OSI和TCP/IP模型掌握TCP协议网络基础编程掌握UDP协议网络基础檹网络高级编程 2、计算机联网的目的 使用远程资源共享信息、程序和数据分布处理 3、基本概念 单服务与多客户端的进程间通信C/S client server 由于&#xff0c;跨计…...

【微信小程序】传参存储

目录 一、本地数据存储 wx.setStorage wx.setStorageSync 1.1、异步缓存 存取数据 1.2、同步缓存 存取数据 二、使用url跳转路径携带参数 2.1、 wx.redirectTo({}) 2.2、 wx.navigateTo({}) 2.3、 wx.switchTab({}) 2.4 、wx.reLaunch({}) 2.5、组件跳转 三、…...

计算机设计大赛 深度学习花卉识别 - python 机器视觉 opencv

文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &a…...

ping多个IP的工具

Ping Tool 项目地址 python开发的IP搜索小工具 ping一个网段所有IP&#xff0c;显示结果查看某个ip地址开放监听的端口配置可保存...

Rust 的 Error 如何使用?

在 Rust 中&#xff0c;错误处理是一个重要且核心的概念。Rust 提供了一种强大的类型系统&#xff0c;允许你明确地处理可能出现的错误。std::error::Error trait 是 Rust 标准库中用于表示错误的基础 trait。实现这个 trait 的类型可以被用作错误类型&#xff0c;并且可以使用…...

Hack The Box-Crafty

目录 信息收集 rustscan whatweb WEB 漏洞利用 漏洞说明 漏洞验证 提权 get user.txt get Administrator 总结 信息收集 rustscan ┌──(root㉿ru)-[~/kali/hackthebox] └─# rustscan -a 10.10.11.249 --range0-65535 --ulimit5000 -- -A -sC [~] Automatically…...

高电平复位电路工作原理详解

单片机复位电路的作用是&#xff1a;使单片机恢复到起始状态&#xff0c;让单片机的程序从头开始执行&#xff0c;运行时钟处于稳定状态、各种寄存器、端口处于初始化状态等等。目的是让单片机能够稳定、正确的从头开始执行程序。一共分为&#xff1a;高电平复位&#xff0c;低…...

了AI而强行AI的做法,构成了人与AI对抗的宿命论

从 ChatGPT到文生图的 Stable Diffusion&#xff0c;再到文生视频的 Sora &#xff0c;每次大语言模型的迭代&#xff0c;以及由此衍生的新产品&#xff0c;都让各行各业的企业主、从业者们&#xff0c;感到无所适从。 普通人可以借助AI的力量“逆天改命”吗&#xff1f; 10多…...

【性能测试】Jmeter+InfluxDB+Grafana 搭建性能监控平台

一、背景 为什么要搭建性能监控平台&#xff1f; 在用 Jmeter 获取性能测试结果的时候&#xff0c;Jmeter自带的测试报告如下&#xff1a; 这个报告有几个很明显的缺点&#xff1a; 只能自己看&#xff0c;无法实时共享&#xff1b;报告信息的展示比较简陋单一&#xff0c;不…...

【YOLOv8模型网络结构图理解】

YOLOv8模型网络结构图理解 1 YOLOv8的yaml配置文件2 YOLOv8网络结构2.1 Conv2.2 C3与C2f2.3 SPPF2.4 Upsample2.5 Detect层 1 YOLOv8的yaml配置文件 YOLOv8的配置文件定义了模型的关键参数和结构&#xff0c;包括类别数、模型尺寸、骨干&#xff08;backbone&#xff09;和头部…...

付强:基于注意力机制的听觉前端处理 | 嘉宾公布

一、智能家居与会议系统专题论坛 智能家居与会议系统专题论坛将于3月28日同期举办&#xff01; 智能会议系统它通过先进的技术手段&#xff0c;提高了会议效率&#xff0c;降低了沟通成本&#xff0c;提升了参会者的会议体验。对于现代企业、政府机构和学术界是不可或缺的。在这…...

C++_包装器

目录 1、包装器的用法 2、包装器的类型 3、包装器的作用 4、包装成员函数 5、bind&#xff08;绑定&#xff09; 5.1 bind的用法 5.2 bind减少参数个数 结语 前言&#xff1a; C11的包装器&#xff0c;总称为function包装器&#xff0c;而包装器又称适配器…...

3588板子部署yoloV5

一 &#xff1a;准备 ubuntu linux X86_64系统 a.安装anaconda b.创建虚拟环境 python3.8 二&#xff1a; 下载rknn-toolkit2 传送门 unzip 解压文件夹 三&#xff1a;pt转onnx模型 四&#xff1a;onnx转rknn模型 a:cd到rknn-toolkit2-master/rknn-toolkit2/packag…...

解决GitHub提交时不显示自己的头像 显示另一个账号(其实也是自己)

git show 看看是否是自己的githup 账号的邮箱 如果不是进行下列操作 git config user.email “你的邮箱地址”,修改邮箱 修改完以后输入git config user.email 检查是否修改成了你的邮箱 如果你想其他项目提交时,也避免此类情况,把上面的两条命令改成 &#xff08;1&#…...

VUE_vue2/3点击区域外触发方法,点击除某个元素触发监听

Vue2 1、自定义指令 // 自定义指令&#xff0c;用于处理点击外部区域的事件 const clickOutside {bind(el, binding) {// 在元素上绑定一个点击事件监听器el.clickOutsideEvent function (event) {// 检查点击事件是否发生在元素的内部if (!(el event.target || el.contai…...

SpringCloud(20)之Skywalking Agent原理剖析

一、Agent原理剖析 使用Skywalking的时候&#xff0c;并没有修改程序中任何一行 Java 代码&#xff0c;这里便使用到了 Java Agent 技术&#xff0c;我 们接下来展开对Java Agent 技术的学习。 1.1 Java Agent Java Agent 是从 JDK1.5 开始引入的&#xff0c;算是一个比较老的…...

容器(0)-DOCKERFILE-安装-常用命令-部署-迁移备份-仓库

1.安装 启动 systemclt start docker //启动 systemctl status docker //状态 docker info systemclt stop docker systemctl status docker systemctl enable docker //开机启动 2.常用命令 镜像查看 docker images 镜像查看 docker status 镜像拉取 docker pull centos:…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...