14.1
当运算符作用会类类型的运算对象时,可以通过运算符重载重新定义该运算符的含义。重载运算符函数必须是类的成员或者至少包含一个类类型的参数。
对于一个重载的运算符而言,其优先级和结合律与对应的内置运算符保持一致。
14.2&&14.6&&14.9
Sale_data.h
#pragma once
#include <string>
#include <iostream>
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:
Sales_data(const std::string &s, unsigned n, double p) :bookNo(s), units_sold(n), revenue(n*p) { }
Sales_data() : Sales_data("", 0, 0.0f) { }
Sales_data(const std::string &s) : Sales_data(s, 0, 0.0f) { }
Sales_data(std::istream &is);
Sales_data& operator+=(const Sales_data&); //符合赋值
std::string isbn() const { return bookNo; }
private:
inline double avg_price() const;
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
std::istream& operator>>(std::istream&, Sales_data&);
std::ostream& operator<<(std::ostream&, const Sales_data&);
Sales_data operator+(const Sales_data&, const Sales_data&);
inline double Sales_data::avg_price() const
{
return units_sold ? revenue / units_sold : 0;
}
sales_data.cpp
#include"Sales_data.h"
Sales_data::Sales_data(std::istream &is) : Sales_data()
{
is >> *this;
}
//输入
std::istream& operator>>(std::istream&is, Sales_data&s)
{
double price = 0.0;
is >> s.bookNo >> s.units_sold >> price;
if (is)
s.revenue = price * s.units_sold;
else
s = Sales_data();
return is;
}
std::ostream& operator<<(std::ostream&os, const Sales_data&s)// 输出
{
os << s.isbn() << " " << s.units_sold << " " << s.revenue << " " << s.avg_price();
return os;
}
Sales_data operator+(const Sales_data&lhs, const Sales_data&rhs) // 加
{
Sales_data sum = lhs;
sum += rhs;
return sum;
}
Sales_data& Sales_data::operator+=(const Sales_data&rhs)//符合赋值
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
int main()
{
return 0;
}
14.3
(1)string
(2)string
(3)vector
(4)string
14.4
(a)非类成员
(b)类成员
©类成员
(d)类成员
(e)非类成员
(f)非类成员
(g)非类成员
(h)类成员
14.5&&14.8
.h
#pragma once
#include <iostream>
using namespace std;
class Date
{
friend ostream& operator<<(ostream& os, const Date& d);
friend bool operator==(const Date&, const Date&);
friend bool operator>(const Date&, const Date&);
friend bool operator<(const Date&, const Date&);
public:
Date() = default;
Date(int y, int m, int d) :year(y), month(m), day(d) {};
int getYear() { return year; }
int getMonth() { return month; }
int getDay() { return day; }
Date& operator+=(const Date& d);
private:
int year;
int month;
int day;
};
.cpp
#include"Date.h"
ostream& operator<<(ostream& os, const Date& d)
{
os << d.year << " " << d.month << " " << d.day << endl;
}
bool operator==(const Date&lhs, const Date&rhs)
{
if (lhs.day == rhs.day&&lhs.month == rhs.month&&lhs.year == rhs.year)
return true;
else
return false;
}
bool operator>(const Date&lhs, const Date&rhs)
{
if (lhs.year > rhs.year)
return true;
else if (lhs.year == rhs.year)
{
if (lhs.month > rhs.month)
return true;
else if (lhs.month == lhs.month)
{
if (lhs.day > rhs.day)
return true;
else
return false;
}
else
return false;
}
else
return false;
}
bool operator<(const Date&d1, const Date&d2)
{
if (d1.year < d2.year) {
return true;
}
else if ((d1.year == d2.year) && (d1.month < d2.month)) {
return true;
}
else if ((d1.month == d2.month) && (d1.day < d2.day)) {
return true;
}
else {
return false;
}
}
14.7
.h
#pragma once
#include<memory>
#include<iostream>
class newString
{
// 重载输出
friend std::ostream &operator<<(std::ostream &os,const newString &str);
public:
newString():elements(nullptr),end(nullptr){}
newString(const char*);
newString(const newString&);
newString& operator=(const newString&);
~newString();
//移动构造函数
newString(newString&&s)noexcept;
newString& operator=(newString&&rhs)noexcept;
const char *c_str() const { return elements; }
size_t size() { return end - elements; }
size_t length() { return end - elements - 1; }
private:
std::pair<char*, char*> alloc_n_copy(const char*,const char*);
void range_initializer(const char*, const char*);
void free();
char *elements;
char *end;
std::allocator<char> alloc;
};
.cpp
#include"newstring.h"
#include<iostream>
#include<algorithm>
#include<vector>
std::pair<char*, char*> newString::alloc_n_copy(const char*beg, const char*end)
{
auto str = alloc.allocate(end - beg);
return { str,std::uninitialized_copy(beg,end,str) };
}
void newString::range_initializer(const char*beg, const char*end)
{
try {
auto newstr = alloc_n_copy(beg, end);
free();
elements = newstr.first;
end = newstr.second;
}
catch (std::bad_alloc& e) {
std::cout << "Failed to allocate memory: " << e.what() << std::endl;
// 这里可以选择如何处理内存分配失败的情况
}
}
newString::newString(const char *s)
{
char *sl = const_cast<char*>(s);
while (*sl)
++sl; //指向尾后
range_initializer(s, ++sl);
}
newString::newString(const newString& rhs)
{
range_initializer(rhs.elements, rhs.end);
std::cout << "copy constructor" << std::endl;
}
//移动构造函数
newString::newString(newString&&s)noexcept :elements(s.elements),end(s.end)
{
s.elements = s.end = nullptr;
std::cout << "移动构造函数调用" << std::endl;
}
newString& newString::operator=(newString&&rhs)noexcept
{
if (this != &rhs)
{
try {
auto newstr = alloc_n_copy(rhs.elements, rhs.end);
free();
elements = newstr.first;
end = newstr.second;
}
catch (std::bad_alloc& e) {
std::cout << "Failed to allocate memory: " << e.what() << std::endl;
// 这里可以选择如何处理内存分配失败的情况
}
}
std::cout << "移动赋值运算符调用" << std::endl;
return *this;
}
void newString::free()
{
if (elements) {
std::for_each(elements, end, [this](char &c) { alloc.destroy(&c); });
alloc.deallocate(elements, end - elements);
}
}
newString::~newString()
{
free();
}
newString& newString::operator = (const newString &rhs)
{
try {
auto newstr = alloc_n_copy(rhs.elements, rhs.end);
free();
elements = newstr.first;
end = newstr.second;
}
catch (std::bad_alloc& e) {
std::cout << "Failed to allocate memory: " << e.what() << std::endl;
}
std::cout << "copy-assignment" << std::endl;
return *this;
}
// 重载输出
std::ostream &operator<<(std::ostream &os, const newString &str)
{
auto beg = str.elements;
while (beg != str.end)
os << *beg++;
return os;
}
14.10
前者是正确的
后者会返回空的Sales_data
14.11
没有检查输入流状态,对于14.10中的(b)会造成错误。
14.12
istream& operator>>(istream& is, Date& d)
{
is >> d.year >> d.month >> d.day;
if (!is)
d = Date();
return is;
}
14.13
Sales_data operator-(const Sales_data&lhs, const Sales_data&rhs)// 减
{
Sales_data sum = lhs;
sum -= rhs;
return sum;
}
Sales_data& Sales_data::operator-=(const Sales_data&s)//符合赋值
{
units_sold -= s.units_sold;
revenue -= s.revenue;
return *this;
}
14.14
1.提高代码复用率:定义 operator+ 的时候,我们需要将两个对象相加,然后创建一个新的对象返回。而定义 operator+= 的时候,我们只需要把一个对象加上另一个对象即。因此,如果先定义 operator+=,再调用operator+=定义operator+,可以提高代码复用率。
2.减少内存分配:在定义 operator+ 的时候,我们需要为新的对象分配内存,然后将两个对象相加得到一个新的对象。这个过程中,需要分配内存,完成对象的拷贝构造函数和析构函数等操作,可能会涉及到大量的内存分配和释放,而这些操作会增加程序的开销。而定义 operator+= 的时候,我们只需要在原有对象上进行操作,不需要额外分配内存,因此可以减少内存分配,提高效率。
14.15
日期应该有一个相减操作:
int operator-(const Date&lhs, const Date&rhs)
{
if (lhs > rhs)
return (lhs.year - rhs.year) * 365 + (lhs.month - rhs.month) * 30 + (lhs.day - rhs.day);
else
return -((lhs.year - rhs.year) * 365 + (lhs.month - rhs.month) * 30 + (lhs.day - rhs.day));
}
14.16
StrBlob and StrBlobPtr
bool operator==(const StrBlob&lhs, const StrBlob&rhs)
{
return *lhs.data == *rhs.data;//data是shared_ptr的指针,所以要解引用
}
bool operator!=(const StrBlob&lhs, const StrBlob&rhs)
{
return !(lhs == rhs);
}
bool operator==(const StrBlobPtr&lhs, const StrBlobPtr&rhs)
{
return lhs.curr == rhs.curr;
}
bool operator!=(const StrBlobPtr&lhs, const StrBlobPtr&rhs)
{
return !(lhs == rhs);
}
StrVec
bool operator==(const StrVec&lhs, const StrVec&rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
}
bool operator!=(const StrVec&lhs, const StrVec&rhs)
{
return !(lhs == rhs);
}
String
bool operator==(const newString&lhs, const newString&rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.elements, lhs.end, rhs.elements);
}
bool operator!=(const newString&lhs, const newString&rhs)
{
return !(lhs == rhs);
}
14.17&&14.19
.h
#pragma once
#include <iostream>
using namespace std;
class Date
{
friend ostream& operator<<(ostream& os, const Date& d);
friend istream& operator>>(istream& os, Date& d);
friend bool operator==(const Date&, const Date&);
friend bool operator>(const Date&, const Date&);
friend bool operator<(const Date&, const Date&);
friend int operator-(const Date&, const Date&);
public:
Date() = default;
Date(int y, int m, int d) :year(y), month(m), day(d) {};
int getYear() { return year; }
int getMonth() { return month; }
int getDay() { return day; }
Date& operator+=(const Date& d);
private:
int year;
int month;
int day;
};
.cpp
#include"Date.h"
ostream& operator<<(ostream& os, const Date& d)
{
os << d.year << " " << d.month << " " << d.day << endl;
}
bool operator==(const Date&lhs, const Date&rhs)
{
if (lhs.day == rhs.day&&lhs.month == rhs.month&&lhs.year == rhs.year)
return true;
else
return false;
}
bool operator>(const Date&lhs, const Date&rhs)
{
if (lhs.year > rhs.year)
return true;
else if (lhs.year == rhs.year)
{
if (lhs.month > rhs.month)
return true;
else if (lhs.month == lhs.month)
{
if (lhs.day > rhs.day)
return true;
else
return false;
}
else
return false;
}
else
return false;
}
bool operator<(const Date&d1, const Date&d2)
{
if (d1.year < d2.year) {
return true;
}
else if ((d1.year == d2.year) && (d1.month < d2.month)) {
return true;
}
else if ((d1.month == d2.month) && (d1.day < d2.day)) {
return true;
}
else {
return false;
}
}
istream& operator>>(istream& is, Date& d)
{
is >> d.year >> d.month >> d.day;
if (!is)
d = Date();
return is;
}
int operator-(const Date&lhs, const Date&rhs)
{
if (lhs > rhs)
return (lhs.year - rhs.year) * 365 + (lhs.month - rhs.month) * 30 + (lhs.day - rhs.day);
else
return -((lhs.year - rhs.year) * 365 + (lhs.month - rhs.month) * 30 + (lhs.day - rhs.day));
}
14.18
strblob and strblobptr
bool operator==(const StrBlob&lhs, const StrBlob&rhs)
{
return *lhs.data == *rhs.data;//data是shared_ptr的指针,所以要解引用
}
bool operator!=(const StrBlob&lhs, const StrBlob&rhs)
{
return !(lhs == rhs);
}
bool operator<(const StrBlob&lhs, const StrBlob&rhs)
{
return std::lexicographical_compare(lhs.data->begin(), lhs.data->end(), rhs.data->begin(), rhs.data->end());
}
bool operator>(const StrBlob&lhs, const StrBlob&rhs)
{
return rhs < lhs;
}
bool operator<=(const StrBlob&lhs, const StrBlob&rhs)
{
return !(lhs > rhs);
}
bool operator>=(const StrBlob&lhs, const StrBlob&rhs)
{
return !(lhs < rhs);
}
//strblobstr
bool operator==(const StrBlobPtr&lhs, const StrBlobPtr&rhs)
{
return lhs.curr == rhs.curr;
}
bool operator!=(const StrBlobPtr&lhs, const StrBlobPtr&rhs)
{
return !(lhs == rhs);
}
bool operator<(const StrBlobPtr&lhs, const StrBlobPtr&rhs)
{
return lhs.curr < rhs.curr;
}
bool operator>(const StrBlobPtr&lhs, const StrBlobPtr&rhs)
{
return rhs < lhs;
}
bool operator<=(const StrBlobPtr&lhs, const StrBlobPtr&rhs)
{
return !(lhs > rhs);
}
bool operator>=(const StrBlobPtr&lhs, const StrBlobPtr&rhs)
{
return !(lhs < rhs);
}
Strvec
bool operator<(const StrVec&lhs, const StrVec&rhs)
{
return std::lexicographical_compare(lhs.begin, lhs.end, rhs.begin, rhs.end);
}
bool operator>(const StrVec&lhs, const StrVec&rhs)
{
return rhs < lhs;
}
bool operator<=(const StrVec&lhs, const StrVec&rhs)
{
return !(lhs > rhs);
}
bool operator>=(const StrVec&lhs, const StrVec&rhs)
{
return !(lhs < rhs);
}
string
bool operator==(const newString&lhs, const newString&rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.elements, lhs.end, rhs.elements);
}
bool operator!=(const newString&lhs, const newString&rhs)
{
return !(lhs == rhs);
}
bool operator<(const newString&lhs, const newString&rhs)
{
return std::lexicographical_compare(lhs.elements, lhs.end, rhs.elements, rhs.end);
}
bool operator>(const newString&lhs, const newString&rhs)
{
return rhs < lhs;
}
bool operator<=(const newString&lhs, const newString&rhs)
{
return!(lhs > rhs);
}
bool operator>=(const newString&lhs, const newString&rhs)
{
return !(lhs < rhs);
}
14.20&&14.21
Sales_data operator+(const Sales_data&lhs, const Sales_data&rhs) // 加
{
Sales_data sum = lhs;
sum += rhs;
return sum;
}
Sales_data& Sales_data::operator+=(const Sales_data&rhs)//符合赋值
{
Sales_data old_data = *this;
*this = old_data + rhs;
return *this;
}
需要临时变量存储对象。
13.22
Sales_data& Sales_data::operator=(const std::string&isbn)
{
*this = Sales_data(isbn);
return *this;
}
13.23
StrVec& StrVec::operator=(std::initializer_list<std::string> il)
{
auto data = alloc_n_copy(il.begin(), il.end());
free();
elements = data.first;
first_free = data.second;
return *this;
}
13.24
不需要,date里面只有浅拷贝
13.25
定义一个重载的赋值运算符
Date& Date::operator=(const string& date)
{
istringstream in(date);
char ch1, ch2;
in >> year >> ch1 >> month >> ch2 >> day;
if (!in || ch1 != '-' || ch2 != '-')
throw std::invalid_argument("Bad date");
if (month < 1 || month >12 || day < 1 || day > 31)
throw std::invalid_argument("Bad date");
return *this;
}
14.26
strblob:
//重载运算符
std::string& operator[](std::size_t n) { check(n, " out of range"); return data->at(n); }
const std::string& operator[](std::size_t n) const
{
check(n, " out of range");
return data->at(n);
}
strblobptr:
std::string& operator[](size_t n)
{
auto p = check(n, "dereference out of range.");
return (*p)[n];
}
const std::string& operator[](size_t n) const
{
auto p = check(n, "dereference out of range.");
return (*p)[n];
}
strvec:
std::string& operator[](std::size_t n) { return elements[n]; }
const std::string& operator[](std::size_t n) const { return elements[n]; }
string:
//重载运算符
char& operator[](std::size_t n) { return elements[n]; }
const char& operator[](std::size_t n) const{ return elements[n]; }
14.27
StrBlobPtr& StrBlobPtr::operator++()
{
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr& StrBlobPtr::operator--()
{
check(--curr, "decrement past begin of StrBlobPtr");
return *this;
}
StrBlobPtr StrBlobPtr::operator++(int)
{
StrBlobPtr ret = *this;
++*this;
return ret;
}
StrBlobPtr StrBlobPtr::operator--(int)
{
StrBlobPtr ret = *this;
--*this;
return ret;
}
14.28
StrBlobPtr& StrBlobPtr::operator+=(size_t n)
{
curr += n;
check(curr, "increment past end of StrBlobPtr");
return *this;
}
StrBlobPtr& StrBlobPtr::operator-=(size_t n)
{
curr -= n;
check(curr, "increment past end of StrBlobPtr");
return *this;
}
StrBlobPtr StrBlobPtr::operator+(size_t n) const
{
StrBlobPtr ret = *this;
ret += n;
return ret;
}
StrBlobPtr StrBlobPtr::operator-(size_t n) const
{
StrBlobPtr ret = *this;
ret -= n;
return ret;
}
14.29
显然递增和递减会改变对象的状态,因此不用const.
14.30
strblobptr
std::string& operator*() const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
std::string* operator->()const {
return &this->operator*();
}
conststrblobptr
inline const string* ConstStrBlobPtr::operator->() const
{
return &this->operator*();
}
inline ConstStrBlobPtr& ConstStrBlobPtr::operator*()
{
auto p=(curr, "dereference past end");
return (*p)[curr];
}
14.31
这个类并没有使用动态内存,所以使用合成的析构函数,根据三五法则,也不需要定义拷贝构造函数,拷贝赋值运算符。
14.32
#pragma once
#include"StrBlob.h"
class strblobptr_ptr
{
public:
strblobptr_ptr() = default;
strblobptr_ptr(StrBlobPtr* p):pointer(p){}
StrBlobPtr& operator*()const
{
return *pointer;
}
StrBlobPtr* operator->()const
{
return pointer;
}
private:
StrBlobPtr* pointer = nullptr;
};
14.33
重载运算符函数的参数数量和该运算符作用的运算对象的数量一样多。函数调用运算符()最多可以传256个参数,因此在重载时,最多也能接受256个参数用作运算。
14.34
#pragma once
class Check_para
{
public:
Check_para(int a) :num(a) {};
int operator()(int num1 ,int b, int c)const
{
return num1 == num ? b : c;
}
private:
int num;
};
14.35
#pragma once
#include<iostream>
#include<string>
class ReadString
{
public:
ReadString(std::istream &ist=std::cin,std::string s=" "):is(ist),rec(s){}
std::string operator()()
{
getline(is, rec);
return rec;
}
private:
std::istream &is;
std::string rec;
};
13.36
.h
#pragma once
#include<iostream>
#include<string>
#include<vector>
class ReadString
{
public:
ReadString(std::istream &ist = std::cin, std::string s = " ", std::vector<std::string> data_ = {}) :
is(ist), rec(s),data(data_){}
std::vector<std::string> operator()()
{
while (getline(is, rec))
data.push_back(rec);
return data;
}
private:
std::istream &is;
std::string rec;
std::vector<std::string> data;
};
.cpp
#include"ReadString.h"
int main()
{
ReadString rs;
auto data = rs();
for (auto &i : data)
std::cout << i << std::endl;
}
14.37
#include<iostream>
class isEqual
{
public:
isEqual(int a,int b ):compare1(a),compare2(b){}
bool operator()()
{
return compare1 == compare2;
}
private:
int compare1,compare2;
};
int main()
{
isEqual is(1,2);
std::cout << is() << std::endl;
}
14.38
#include <iostream>
#include<fstream>
#include<vector>
#include<map>
using namespace std;
class IsInRange
{
public:
IsInRange(size_t s):size(s) {};
bool operator()(size_t s)
{
return size == s;
}
size_t getSize() { return size; }
private:
size_t size;
};
int main()
{
vector<IsInRange>vec;
map<size_t, int>len_cnt_table;
for (int i = 1; i < 11; i++)
{
vec.push_back(i);
len_cnt_table[i] = 0;
}
ifstream fs("test.txt");
string word;
while (fs >> word)
{
for (auto i : vec)
{
if (i(word.size()))
{
++len_cnt_table[i.getSize()];
}
}
}
for (auto i : len_cnt_table) {
cout << i.first << " " << i.second << endl;
}
}
14.39
#include <iostream>
#include<string>
#include<fstream>
#include<vector>
#include<map>
using namespace std;
class IsInRange
{
public:
IsInRange(size_t l,size_t b):lowest(l),biggest(b) {};
bool operator()(const string&s)
{
return lowest <= s.size() && s.size() <= biggest;
}
size_t getLowest() { return lowest; }
size_t getBiggest() { return biggest; }
private:
size_t lowest;
size_t biggest;
};
int main()
{
vector<IsInRange>vec;
map<string, int>len_cnt_table;
vec.push_back({ 1,9 });
vec.push_back({ 1,9 });
ifstream fs("test.txt");
string word;
while (fs >> word) {
for (auto i : vec) {
if (i(word)) {
++len_cnt_table[to_string(i.getLowest()) + "-" + to_string(i.getBiggest())];
}
}
}
for (auto i : len_cnt_table) {
cout << "The length of word in range " << i.first << " is " << i.second << endl;
}
}
14.40
class compareSize
{
public:
compareSize() {}
compareSize(std::size_t len) : sz(len) {}
bool operator()(const std::string &s) {
return s.size() > sz;
}
bool operator()(const std::string &s1, const std::string &s2) {
return s1.size() <s2.size();
}
private:
std::size_t sz;
};
14.41
使用lambda可读性更好,
次数多用类,次数少用lambda.
14.42
#include<vector>
#include<algorithm>
#include<string>
#include<iostream>
#include<functional>
using std::placeholders::_1;
int main()
{
std::vector<int> vec = { 1,12,123,1234 };
int count = std::count_if(vec.begin(), vec.end(),std::bind(std::greater<int>(), _1, 1024));
std::cout << count << std::endl;
std::vector<std::string> v2 = { "pooh","pooo" };
auto iter = std::find_if(v2.begin(), v2.end(), std::bind(std::not_equal_to<std::string>(), _1, "pooh"));
std::cout << *iter << std::endl;
std::transform(vec.begin(),vec.end(),vec.begin(), std::bind(std::multiplies<int>(), _1, 2));
for (auto &i : vec)
std::cout << i << " ";
return 0;
}
14.43
#include<vector>
#include<algorithm>
#include<string>
#include<iostream>
#include<functional>
using std::placeholders::_1;
int main()
{
std::vector<int> vec = { 1,12,14,15 };
int num;
std::cin >> num;
std::modulus<int> mod;
auto predi = [&](int i) {return 0 == mod(num, i); };
auto is_ava = std::any_of(vec.begin(), vec.end(), predi);
std::cout << is_ava << std::endl;
return 0;
}
14.44
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<iostream>
#include<functional>
using std::placeholders::_1;
class add
{
public:
int operator()(int a, int b)
{
return a + b;
}
};
class minus
{
public:
int operator()(int a, int b)
{
return a - b;
}
};
class multiple
{
public:
int operator()(int a, int b)
{
return a * b;
}
};
class divide
{
public:
int operator()(int a, int b)
{
return a / b;
}
};
class modeules
{
public:
int operator()(int a, int b)
{
return a % b;
}
};
int main()
{
std::map<std::string, std::function<int(int, int)>> calculator = {
{"+",add()},{"-",minus()},{"*",multiple()},{"/",divide()},{"%",modeules()} };
std::cout << calculator["+"](10,5) << std::endl;
return 0;
}
14.45
// 类型转换
explicit operator std::string()const { return bookNo; }
explicit operator double()const { return revenue; }
14.46
应该定义,并且需要把他们声明为显示的,防止无意中的隐式转换。
14.47
第一个表示返回类型是一个const int
第二个表示const成员函数。即不会修改对象的状态
14.48
不需要,因为Date类的设计目的是表示一个具体的日期,那么不需要bool类型转换运算符。因为这种情况下,将日期对象转换为bool类型并没有实际的意义,也不能清晰地表达出对象所代表的信息。
14.49
explicit operator bool ()const{
if (month < 1 || month> 12) return false;
if (day < 1 || day> 30) return false;
return true;
}
14.50
ex1会发生二义性错误
ex2会通过类型转换运算符operator float()进行转换;
14.51
1.calc(dval)->calc(int(dval))
2.calc(dval)->calc(operator(dval))
3.calc(dval)->calc(LongDouble(dval))
优先使用标准类型转换,也就是第一种
14.52
ld = si + ld;
1.将ld转换为SmallInt。
2.将si转换为LongDouble,ld转换为double。
具有二义性。
ld = ld + si;
精确匹配LongDouble operator+ (const SmallInt&);
14.53
不合法。
可以将smallint中改为double:
operator double() const {return val;}