zoukankan      html  css  js  c++  java
  • C++ Primer第5版 第十四章课后练习答案

    练习14.1

    区别:

      1.可以直接调用重载的运算符

      2.至少有一个运算对象是类类型

      3.无法保留运算对象的求值顺序规则和短路求值规则

    共同点:

      重载运算符的优先级和结合律与对应的内置运算符保持一致

    练习14.2

    #ifndef SALES_DATA_H
    #define SALES_DATA_H
    #include <string>
    #include <ostream>
    using std::string;
    using std::istream;
    using std::ostream;
    using std::endl;
    class Sales_data {
        friend istream& operator>>(istream& is, Sales_data& it);
        friend ostream& operator<<(ostream& os, Sales_data& it);
    private:
        string bookNo;
        unsigned units_sold = { 0 };
        double revenue = { 0.0 };
    public:
        const string& isbn() const { return bookNo; }
        Sales_data& operator+=(const Sales_data& rhs) {
            units_sold += rhs.units_sold;
            revenue += rhs.revenue;
            return *this;
        }
        Sales_data(string bn, unsigned us = 0, double re = 0.0) :bookNo(bn), units_sold(us), revenue(re) { std::cout << "Sales_data(string bn, unsigned us = 0, double re = 0.0)" << std::endl;}
        Sales_data() :Sales_data("") { std::cout << "Sales_data()" << std::endl; }
        Sales_data(istream& is) :Sales_data() { is>> *this; std::cout << "Sales_data(istream& is)" << std::endl; }
    };
    
    Sales_data operator+(Sales_data& lhs, Sales_data& rhs) {
        Sales_data sum = lhs;
        sum += rhs;
        return sum;
    }
    
    istream & operator>>(istream& is, Sales_data& it) {
        is >> it.bookNo >> it.units_sold >> it.revenue;
        return is;
    }
    
    ostream& operator<<(ostream& os, Sales_data& it) {
        os << it.isbn() << " " << it.units_sold << " " << it.revenue << endl;
        return os;
    }
    
    #endif // !SALES_DATA_H

    练习14.3

     "cobble" == "stone";    //两者元素中既不是string也不是vector,因此两个版本都不是
     svec1[0] == svec2[0];    //string    
     svec1 == svec2;            //vector
     svec1[0] == "stone";    //string

    练习14.4

    (a) %    算数运算符,通常为普通的非成员函数

    (b) %=   复合赋值运算符,通常为成员函数

    (c) ++    改变对象状态的运算符,通常为成员函数

    (d) ->    必须是成员函数

    (e) <<    通常为普通的非成员函数

    (f) &&    通常为普通的非成员函数

    (g) ==    通常为普通的非成员函数

    (h) ()    必须是成员函数

    练习14.5

    #ifndef DATE_H_
    #define DATE_H_
    #include<string>
    using std::string;
    class Date
    {
    public:
        Date(string&);
        ~Date();
        unsigned getYear()const { return year; }
        unsigned getMonth() const { return month; }
        unsigned getDay() const { return day; }
    private:
        unsigned year;
        unsigned month;
        unsigned day;
        void str_to_month(string &str,string::size_type& pos);
    };
    
    Date::Date(string &s)
    {
        string::size_type pos1, pos2;
        if (pos1 = s.find_first_of(",/") == string::npos) {
            pos1 = s.find_first_of(" ");
            pos2 = s.find_last_of(" ");
            str_to_month(s, pos1);
            day = stoul(s.substr(pos1 + 1, pos2));
            year = stoul(s.substr(pos2 + 1, s.size()));
        }
        else if (pos1 = s.find_first_of(",") == string::npos) {
            pos1 = s.find_first_of("/");
            pos2 = s.find_last_of("/");
            str_to_month(s, pos1);
            day = stoul(s.substr(pos1 + 1, pos2));
            year = stoul(s.substr(pos2 + 1, s.size()));
        }
        else if (pos1 = s.find_first_of("/") == string::npos) {
            pos1 = s.find_first_of(" ");
            pos2 = s.find_last_of(",");
            str_to_month(s, pos1);
            day = stoul(s.substr(pos1 + 1, pos2));
            year = stoul(s.substr(pos2 + 1, s.size()));
        }
        else
        {
            day = month = year = 0;
        }
    }
    
    Date::~Date()
    {
    }
    
    inline void Date::str_to_month(string& s, string::size_type& pos1)
    {
        if (s.substr(0, pos1) == "Jan" || s.substr(0, pos1) == "January") {
            month = 1;
        }
        else if (s.substr(0, pos1) == "Feb" || s.substr(0, pos1) == "February") {
            month = 2;
        }
        else if (s.substr(0, pos1) == "Mar" || s.substr(0, pos1) == "March") {
            month = 3;
        }
        else if (s.substr(0, pos1) == "Apr" || s.substr(0, pos1) == "April") {
            month = 4;
        }
        else if (s.substr(0, pos1) == "May" || s.substr(0, pos1) == "May") {
            month = 5;
        }
        else if (s.substr(0, pos1) == "Jun" || s.substr(0, pos1) == "June") {
            month = 6;
        }
        else if (s.substr(0, pos1) == "Jul" || s.substr(0, pos1) == "July") {
            month = 7;
        }
        else if (s.substr(0, pos1) == "Aug" || s.substr(0, pos1) == "August") {
            month = 8;
        }
        else if (s.substr(0, pos1) == "Sept" || s.substr(0, pos1) == "September") {
            month = 9;
        }
        else if (s.substr(0, pos1) == "Oct" || s.substr(0, pos1) == "October") {
            month = 10;
        }
        else if (s.substr(0, pos1) == "Nov" || s.substr(0, pos1) == "November") {
            month = 11;
        }
        else if (s.substr(0, pos1) == "Dec" || s.substr(0, pos1) == "December") {
            month = 12;
        }
        else {
            month = stoul(s.substr(0, pos1));
        }
    }
    
    std::ostream& operator<< (std::ostream& os,const Date& d)
    {
        os << d.getYear() << "-" << d.getMonth() << "-" << d.getDay();
        return os;
    }
    
    #endif // !DATE_H_

    练习14.6

    ostream& operator<<(ostream& os, const Sales_data& it) {
        os << it.isbn() << " " << it.units_sold << " " << it.revenue;
        return os;
    }

    练习14.7

    ostream& operator<<(ostream& os, const String& s)
    {
        auto sl = s.begin();
        while (sl != s.end()) os << *(sl++);
        return os;
    }

    练习14.8

    std::ostream& operator<< (std::ostream& os,const Date& d)
    {
        os << d.getYear() << "-" << d.getMonth() << "-" << d.getDay();
        return os;
    }

    练习14.9

    istream & operator>>(istream& is, Sales_data& it) {
        is >> it.bookNo >> it.units_sold >> it.revenue;
        if (!is)
            it = Sales_data();
        return is;
    }

    练习14.10

    (a)

    0-201-99999-9 10 24.95
    0-201-99999-9 10 24.95

    (b)

    10 24.95 0-210-99999-9
    10 24 0.95

    练习14.11

    没有输入检查,什么也不会发生

    练习14.12

    std::istream& operator>> (std::istream& is, Date& d)
    {
        is >> d.year >> d.month >> d.day;
        if (!is) {
            std::string s = "";
            d = Date(s);
        }
        return is;
    }

    练习14.13

    还应该支持operator-运算符,因此也应该支持operator-=复合运算符

    Sales_data& operator-=(const Sales_data& rhs) {
        units_sold -= rhs.units_sold;
        revenue -= rhs.revenue;
        return *this;
    }
    
    Sales_data operator-(Sales_data& lhs, Sales_data& rhs) {
        Sales_data sum = lhs;
        sum -= rhs;
        return sum;
    }

    练习14.14

    因为operator+=不需要创建临时空间,所以调用operator+=比其它方法更奏效

    练习14.15

    不是,因为Date类对于类对象的+-计算会产生二义性

    练习14.16

    StrBlob类,StrBlobPtr类

    inline bool operator==(const StrBlob& lhs, const StrBlob& rhs)
    {
        return *lhs.data == *rhs.data;
    }
    
    inline bool operator!=(const StrBlob& lhs, const StrBlob& rhs)
    {
        return !(lhs==rhs);
    }
    
    // named equality operators for StrBlobPtr
    inline
    bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
    {
        auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
        // if the underlying vector is the same 
        if (l == r) 
            // then they're equal if they're both null or 
            // if they point to the same element
            return (!r || lhs.curr == rhs.curr);
        else
            return false; // if they point to difference vectors, they're not equal
    }
    
    inline
    bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs)
    {
        return !(lhs==rhs); 
    }
    
    // named equality operators for StrBlobPtr
    inline
    bool operator==(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
    {
        auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
        // if the underlying vector is the same 
        if (l == r)
            // then they're equal if they're both null or 
            // if they point to the same element
            return (!r || lhs.curr == rhs.curr);
        else
            return false; // if they point to difference vectors, they're not equal
    }
    
    inline
    bool operator!=(const ConstStrBlobPtr& lhs, const ConstStrBlobPtr& rhs)
    {
        return !(lhs==rhs);
    }

    StrVec类

    bool operator==(const StrVec& lhs, const StrVec& rhs)
    {
        if (lhs.size() != rhs.size()) {
            return false;
        }
        else {
            for (auto l_iter = lhs.begin(),r_iter = rhs.begin(); l_iter != lhs.end(); ++l_iter, ++r_iter) {
                if (*l_iter != *r_iter) {
                    return false;
                }
            }
        }
        return true;
    }
    inline bool operator!=(const StrVec& lhs, const StrVec& rhs)
    {
        return !(lhs==rhs);
    }

    String类

    inline bool operator==(const String& lhs, const String& rhs)
    {
        if (lhs.size() != rhs.size()) {
            return false;
        }
        else {
            for (auto l_iter = lhs.begin(), r_iter = rhs.begin(); l_iter != lhs.end(); ++l_iter, ++r_iter) {
                if (*l_iter != *r_iter) {
                    return false;
                }
            }
        }
        return true;
    }
    inline bool operator!=(const String& lhs, const String& rhs)
    {
        return !(lhs == rhs);
    }

    练习14.19

    inline bool operator==(const Date& lhs, const Date& rhs)
    {
        return lhs.year==rhs.year&& lhs.month == rhs.month && lhs.day == rhs.day;
    }
    
    inline bool operator!=(const Date& lhs, const Date& rhs)
    {
        return !(lhs == rhs);
    }

    练习14.20

    Sales_data& operator+=(const Sales_data& rhs) {
            units_sold += rhs.units_sold;
            revenue += rhs.revenue;
            return *this;
        }
    
    Sales_data operator+(Sales_data& lhs, Sales_data& rhs) {
        Sales_data sum = lhs;
        sum += rhs;
        return sum;
    }

    练习14.21

    Sales_data operator+(const Sales_data& lhs, const Sales_data& rhs) {
        Sales_data sum = lhs;
        sum.units_sold += rhs.units_sold;
        sum.revenue += rhs.revenue;
        return sum;
    }
    
        Sales_data& operator+=(const Sales_data& rhs) {
            const Sales_data tmp = *this;
            *this = tmp + rhs;
            return *this;
        }

    operator+=运算符调用operator+运算符前需要创建临时内存空间

    练习14.22

    Sales_data& Sales_data::operator=(string& s)
    {
        bookNo = s;
        units_sold = 0;
        revenue = 0;
    }

    练习14.23

    inline StrVec& StrVec::operator=(std::initializer_list<std::string> il)
    {
        auto newdata = alloc_n_copy(il.begin(), il.end());
        free();
        elements = newdata.first;
        first_free = cap = newdata.second;
        return *this;
    }

    练习14.24

    Date类不需要实现拷贝赋值和移动赋值运算符,因为Date类中只含有三个int变量,默认的浅拷贝就能满足要求。

    inline Date& Date::operator=(const Date& d)
    {
        year = d.year;
        month = d.month;
        day = d.day;
    }
    
    inline Date& Date::operator=(Date&&d)
    {
        year = d.year;
        month = d.month;
        day = d.day;
    }

    练习14.25

    还应该定义赋值运算符,参数为string,将date作为一个字符串赋值给Date类。

    inline Date& Date::operator=(string&s)
    {
        string::size_type pos1, pos2;
        if (pos1 = s.find_first_of(",/") == string::npos) {
            pos1 = s.find_first_of(" ");
            pos2 = s.find_last_of(" ");
            str_to_month(s, pos1);
            day = stoul(s.substr(pos1 + 1, pos2));
            year = stoul(s.substr(pos2 + 1, s.size()));
        }
        else if (pos1 = s.find_first_of(",") == string::npos) {
            pos1 = s.find_first_of("/");
            pos2 = s.find_last_of("/");
            str_to_month(s, pos1);
            day = stoul(s.substr(pos1 + 1, pos2));
            year = stoul(s.substr(pos2 + 1, s.size()));
        }
        else if (pos1 = s.find_first_of("/") == string::npos) {
            pos1 = s.find_first_of(" ");
            pos2 = s.find_last_of(",");
            str_to_month(s, pos1);
            day = stoul(s.substr(pos1 + 1, pos2));
            year = stoul(s.substr(pos2 + 1, s.size()));
        }
        else
        {
            day = month = year = 0;
        }
    }

    练习14.26

    StrBlob类

    inline std::string& StrBlob::operator[](size_t n)
    {
        check(n, "out of range");
        return data->at(n);
    }
    inline const std::string& StrBlob::operator[](size_t n) const
    {
        check(n, "out of range");
        return data->at(n);
    }

    StrBlobPtr类

    inline std::string& StrBlobPtr::operator[](size_t n)
    {
        auto ret=check(n, "out of range");
        return (*ret)[n];
    }
    
    inline const std::string& StrBlobPtr::operator[](size_t n) const
    {
        auto ret = check(n, "out of range");
        return (*ret)[n];
    }

    StrVec类

    inline std::string& StrVec::operator[](size_t n)
    {
        if (size() > n && n >= 0)return *(elements + n);
    }
    inline const std::string& StrVec::operator[](size_t n) const
    {
        if (size() > n && n >= 0)return *(elements + n);
    }

    String类

    char& operator[](size_t n) { return elements[n]; };
    const char& operator[](size_t n)const { return elements[n]; };

    练习14.27

    inline StrBlobPtr& StrBlobPtr::operator++()
    {
        check(curr, "increment past out end of StrBlobPtr");
        ++curr;
        return *this;
    }
    inline StrBlobPtr StrBlobPtr::operator++(int)
    {
        StrBlobPtr ret = *this;
        ++*this;
        return ret;
    }
    
    inline StrBlobPtr& StrBlobPtr::operator--()
    {
        --curr;
        check(curr, "increment past begin end of StrBlobPtr");
        return *this;
    }
    
    inline StrBlobPtr StrBlobPtr::operator--(int)
    {
        StrBlobPtr ret = *this;
        --* this;
        return ret;
    }

    练习14.28

    inline StrBlobPtr& StrBlobPtr::operator+=(size_t n)
    {
        curr += n;
        check(curr, "increment past out end of StrBlobPtr");
        return *this;
    }
    
    inline StrBlobPtr StrBlobPtr::operator+(size_t n) const
    {
        StrBlobPtr ret = *this;
        ret += n;
        return ret;
    }
    
    inline StrBlobPtr& StrBlobPtr::operator-=(size_t n)
    {
        curr -= n;
        check(curr, "increment past begin end of StrBlobPtr");
        return *this;
    }
    
    inline StrBlobPtr StrBlobPtr::operator-(size_t n) const
    {
        StrBlobPtr ret = *this;
        ret -= n;
        return ret;
    }

    练习14.29

    递增和递增需要改变对象元素,因此不定义const版本

    练习14.30

    inline std::string& StrBlobPtr::operator*() const
    {
        auto p = check(curr, "dereference past end");
        return (*p)[curr];
    }
    
    inline std::string* StrBlobPtr::operator->() const
    {
        return &this->operator*();
    }
    
    
    inline const std::string& ConstStrBlobPtr::operator*() const
    {
        auto p = check(curr, "dereference past end");
        return (*p)[curr];
    }
    inline const std::string* ConstStrBlobPtr::operator->() const
    {
        return &this->operator*();
    }

    练习14.31

    StrBlobPtr没有动态分配的内存,因此不需要自定义的析构函数,又由三五法则可知不需要定义拷贝构造函数和赋值运算符

    练习14.32

    class StrBlobPtr_pointer
    {
    public:
        StrBlobPtr_pointer() = default;
        StrBlobPtr_pointer(StrBlobPtr* p) : pointer(p) { }
    
        StrBlobPtr& operator *() const;
        StrBlobPtr* operator->() const;
    
    private:
        StrBlobPtr* pointer = nullptr;
    };
    
    StrBlobPtr&
    StrBlobPtr_pointer::operator *() const
    {
        return *(this->pointer);
    }
    
    StrBlobPtr*
    StrBlobPtr_pointer::operator ->() const
    {
        return &this->operator*();
    }
    
    int main(int argc,char*argv[]) {
        StrBlob sb{ "hello", "world" };
        StrBlobPtr iter = sb.begin();
        StrBlobPtr_pointer p(&iter);
        std::cout << p->deref() << std::endl;
    }

    练习14.33

    重载的函数调用运算符和该运算符能接受的运算对象相同,因此最大值为256

    练习14.34

    struct compInt
    {
        const int operator()(const int val1, const int val2, const int val3)const {
            return (val1 ? val2 : val3);
        }
    };
    
    int main(int argc,char*argv[]) {
        compInt c;
        std::cout << c(1,2,3) << std::endl;
    }

    练习14.35

    class ScanfString
    {
    public:
        ScanfString(istream& i ) :is(i){ getline(i, str); }
        string operator()() { 
            return str; 
        }
    private:
        istream& is;
        string str;
    };
    
    int main(int argc,char*argv[]) {
        ScanfString c(cin);
        std::cout << c() << std::endl;
    }

    练习14.36

    class ScanfString
    {
    public:
        ScanfString(istream& i ) :is(i){ 
            string s;
            while (i) {
                getline(i, s);
                str.emplace_back(s);
            }
        }
        void operator()() { 
            for_each(str.begin(), str.end(), [&](string& s) {cout << s << endl; });
        }
    private:
        istream& is;
        vector<string> str;
    };
    
    int main(int argc,char*argv[]) {
        ScanfString c(cin);
        c(); 
    }

    练习14.37

    class CompInt
    {
    public:
        CompInt(int i ) :comp(i){}
        bool operator()(int i) { 
            return comp == i;
        }
    private:
        int comp;
    };
    
    int main(int argc,char*argv[]) {
        vector<int> vi{ 0,1,2,3,4,3,4,5 };
        CompInt ci(3);
        replace_if(vi.begin(), vi.end(), ci,10);
        for_each(vi.begin(), vi.end(), [](int& i) {cout << i << " "; });
    }

    练习14.38

    class CompInt
    {
    public:
        CompInt(size_t l, size_t u) :lower(l), upper(u) {}
        CompInt(size_t c = 0) :lower(c), upper(c) {}
        bool operator()(string &s) { 
            return(s.length() >= lower && s.length() <= upper);
        }
    private:
        size_t lower;
        size_t upper;
    };
    
    
    
    int main(int argc,char*argv[]) {
        map<size_t, size_t> words_len;
        for (size_t i = 1; i < 11; ++i) {
            ifstream ifs(argv[1]);
            CompInt ci(i);
            for (std::string word; ifs >> word;) {
                if (ci(word)) ++words_len[i];
            }
        }  
        for (auto i : words_len) {
            cout << i.first << ":" << i.second << endl;
        }
    }

    练习14.39

    class CompInt
    {
    public:
        CompInt(size_t l, size_t u) :lower(l), upper(u) {}
        CompInt(size_t c = 0) :lower(c), upper(c) {}
        bool operator()(string &s) { 
            return(s.length() >= lower && s.length() <= upper);
        }
    private:
        size_t lower;
        size_t upper;
    };
    
    
    
    int main(int argc,char*argv[]) {
        map<size_t, size_t> words_len;
        ifstream ifs(argv[1]);
        CompInt ci1(1,9);
        CompInt ci2(10,SIZE_MAX);
        for (std::string word; ifs >> word;) {
            if (ci1(word)) ++words_len[1];
            else if (ci2(word)) ++words_len[10];
        }
        for (auto i : words_len) {
            cout << i.first << ":" << i.second << endl;
        }
    }

    练习14.40

    class compString
    {
    public:
        compString(size_t s):sz(s){}
        const bool operator()(const string& str1, const string& str2)const {
            return (str1.size() >= str2.size());
        }
        const bool operator()(const string& str)const {
            return str.size() > sz;
        }
    private:
        size_t sz;
    };
    
    class printStr
    {
    public:
        void operator()(const string& str)const {
            cout << str << " ";
        }
    private:
    
    };
    
    
    void elimDups(vector<string>& words)
    {
        sort(words.begin(), words.end());
        auto end_unique = unique(words.begin(), words.end());
        words.erase(end_unique, words.end());
    }
    
    void biggies(vector<string>& words, size_t sz)
    {
        elimDups(words);
        compString cs(sz);
        printStr ps;
        stable_sort(words.begin(), words.end(), cs);
        auto wc = stable_partition(words.begin(), words.end(), cs);
        for_each(words.begin(), wc, ps);
    }

    练习14.41

    在某些时候, 使用lamdba更方便。当函数方法不经常使用或不复杂时, 可以使用 lambda, 而当调用函数方法实现较复杂且要被频繁调用则使用类。

    练习14.42

    int main(int argc, char* argv[])
    {
        vector<int> iv;
        for (auto i = 1000; i < 2000; i+=2)
            iv.emplace_back(i);
        cout<<"大于1024的数字有"<<count_if(iv.begin(), iv.end(), bind(std::greater<int>(),_1, 1024))<<""<<endl;
    
        vector<string> svec = { "pooh", "apple", "banana", "pooh" };
        auto word = find_if(svec.cbegin(), svec.cend(), bind(std::not_equal_to<string>(), _1, "pooh"));
        cout << *word << endl;
    
        transform(iv.begin(), iv.end(), iv.begin(), bind(std::multiplies<int>(), _1, 2));
        for (auto i : iv) {
            cout << i << " ";
        }
    }

    练习14.43

    int main(int argc, char* argv[])
    {
        vector<int> iv{1,2,4,8,16};
        if (any_of(iv.begin(), iv.end(), bind(std::modulus<int>(), 1024, _1))) {
            cout << "给定int值不能被int容器中的所有元素整除" << endl;
        }
        else {
            cout << "给定int值能被int容器中的所有元素整除" << endl;
        }  
    }

    练习14.44

    int main(int argc, char* argv[])
    {
        std::map<std::string, std::function<int(int, int)>> binops = {
        {"+", std::plus<int>()},                               
        {"-", std::minus<int>()},                  
        {"/", std::divides<int>()},                          
        {"*", std::multiplies<int>()}, 
        {"%", std::modulus<int>()}                              
        };
        while (true) {
            int n1, n2;
            std::string s;
            std::cin >> n1 >> s >> n2;
            std::cout << binops[s](n1, n2) << endl;
        }
        return 0;
    }

    练习14.45

        explicit operator string() const { return bookNo; }
        explicit operator double() const { return revenue; }
    int main(int argc, char* argv[])
    {
        Sales_data s;
        cout << static_cast<string>(s) << endl;
        cout << static_cast<double>(s) << endl;
        return 0;
    }

    练习14.46

    不应该定义上述两种类型转换运算符,因为对于使用者来说理解难度高,应该尽量避免让使用者去进行强制类型转换。应该声明为explicit,避免隐式的强制类型转换

    练习14.47

    struct Integal {
        operator const int();//返回的类型是const类型
        operator int() const;//不允许对象在函数内被修改
    };

    练习14.48

    应该含有,因为Date类需要进行格式判断,又因为向bool的类型转换通常用在条件部分,因此一般定义成explicit的

    练习14.49

    class Date
    {
        friend std::istream& operator>> (std::istream& , Date& );
        friend bool operator==(const Date& lhs, const Date& rhs);
        friend bool operator!=(const Date& lhs, const Date& rhs);
    public:
        Date():day(0),month(0),year(0) {}
        Date(string&);
        Date& operator=(const Date&);
        Date& operator=(Date&&)noexcept;
        Date& operator=(string&);
        ~Date();
        unsigned getYear()const { return year; }
        unsigned getMonth() const { return month; }
        unsigned getDay() const { return day; }
        explicit operator bool() const {
            return 1 <= month && month <= 12 && 1 <= day && day <= month_days[((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) ? 1 : 0][month - 1];
        }
    private:
        unsigned year;
        unsigned month;
        unsigned day;
        static vector<vector<int>> month_days;
        void str_to_month(string &str,string::size_type& pos);
    };
    
    vector<vector<int>> Date::month_days{ { 31,28,31,30,31,30,31,31,30,31,30,31 } ,{ 31,29,31,30,31,30,31,31,30,31,30,31 } };

    练习14.50

    struct LongDouble {
        LongDouble (double = 0.0);
        operator double();
        operator float();
    };
    LongDouble ldObj;
    int ex1 = ldObj;          // 在将ldObj转换为int时,类定义的类型转换都无法精准匹配,因此会产生二义性,可能先执行 operator double(), 再进行double到int的转换。也可能调用operator float(),再进行float到int的转换。
    float ex2 = ldObj;        // 调用operator float()

    练习14.51

    会优先调用calc(int),因为doube转int是标准类型转换,而LongDouble转int是用户自定义转换。

    练习14.52

    struct LongDouble {
        LongDouble operator+ (const SmallInt&);
    };
    LongDouble operator+(LongDouble&, double);
    SmallInt si;
    LongDouble ld;
    ld = si + ld;//没有与这些操作数匹配的+运算符,这是因为上面定义的两个操作符都不够精确 
    ld = ld + si;//C++ LongDouble LongDouble::operator+(const SmallInt &)

    练习14.53

    SmallInt s1;
    double d = s1 + 3.14;

    不合法,因为s1可以隐式转换为int型,而内置operator+支持int和double的加法,或者将double类型3.14转换为int再转换为SmallInt进行operator+为两个SmallInt的加法,存在二义性

    改为

    int main(int argc, char* argv[])
    {
        SmallInt s1;
        double d = s1 + SmallInt(3.14);
        return 0;
    }
  • 相关阅读:
    信息安全系统设计基础第二周学习总结(20135213)
    《深入理解计算机系统》第一节课课堂笔记(20135213)
    (20135213)信息安全系统设计基础第一周学习总结(共12课)课程(6~12)
    (20135213)信息安全系统设计基础第一周学习总结(共12课)课程(1~5)
    实验五 — — Java网络编程及安全
    20135220谈愈敏--信息安全系统设计基础期中总结
    20135220谈愈敏-第三章家庭作业
    20135220谈愈敏--信息安全系统设计基础第六周学习总结
    20135220谈愈敏-第二章家庭作业
    20135220谈愈敏--信息安全系统设计基础第五周学习总结
  • 原文地址:https://www.cnblogs.com/GodZhuan/p/14022397.html
Copyright © 2011-2022 走看看