C++ Primer: Chapter 14 Operator and Type Conversion

Homework

Test 14.2

class my_sales_data
{
	friend std::istream& operator>>(std::istream&, my_sales_data&);
	friend std::ostream& operator<<(std::ostream&, const my_sales_data&);
	friend my_sales_data operator+(const my_sales_data&, const my_sales_data&);

public:
	//构造函数(声明)
	//my_sales_data() : units_sold(0), revenue(0.0) {}; //使用类内初始值
	my_sales_data(std::string s) : bookNo(s) {};
	my_sales_data(std::string s, unsigned n, double r) : bookNo(s), units_sold(n), revenue(r) { std::cout << 'a' << std::endl; };
	my_sales_data() : my_sales_data("1001", 0, 0) { std::cout << 'b' << std::endl; }; //使用委托构造函数
	my_sales_data(std::istream&);
	
	inline double avg_price() const;
	std::string isbn() const { return bookNo; }
	
	my_sales_data& operator+=(const my_sales_data&);

private:
	//成员变量
	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;

};

//非成员接口函数(声明)
my_sales_data operator+(const my_sales_data&, const my_sales_data&);
std::ostream& operator<<(std::ostream&, const my_sales_data&);
std::istream& operator>>(std::istream&, my_sales_data&);

//===== 构造函数 =====
my_sales_data::my_sales_data(std::istream& is)
{
	is >> *this;
}

//===== 成员函数 =====
inline double my_sales_data::avg_price() const
{
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}

my_sales_data& my_sales_data::operator+=(const my_sales_data& rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.revenue;
	return *this;
}

//===== 非成员接口函数 ======

std::istream& operator>>(std::istream& is, my_sales_data& item)
{
	double price = 0;
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = item.units_sold * price;
	return is;
}

std::ostream& operator<<(std::ostream& os, const my_sales_data & item)
{
	os << item.bookNo << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
	return os;
}

my_sales_data operator+(const my_sales_data& lhs, const my_sales_data& rhs)
{
	my_sales_data sum = lhs;
	sum += rhs;
	return sum;
}

Test 14.16

strblob

bool operator==(const strblob& lhs, const strblob& rhs)
{
	return lhs.data == rhs.data;
}
bool operator!=(const strblob& lhs, const strblob& rhs)
{
	return !(lhs == rhs);
}

StrBlobPtr

bool operator==(const strblobptr& lhs, const strblobptr& rhs) {
	auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
	// 若底层的 vector 是同一个
	if (l == r)
		// 则两个指针都是空,或者指向相同元素时,它们相等
		return (!r || lhs.curr == rhs.curr);
	else
		return false;       // 若指向不同 vector,则不可能相等
}

bool operator!=(const strblobptr& lhs, const strblobptr& rhs) {
	return !(lhs == rhs);
}

StrVec

bool operator==(const StrVec& lhs, const StrVec& rhs)
{
	if (lhs.size() != rhs.size() || lhs.capacity() != rhs.capacity())
		return false;
	for (auto it1 = lhs.begin(), it2 = rhs.begin(); it1 != lhs.end() && it2 != rhs.end(); ++it1, ++it2)
	{
		if (*it1 != *it2)
			return false;
	}
	return true;
		
}
bool operator!=(const StrVec& lhs, const StrVec& rhs)
{
	return !(lhs == rhs);
}

String

bool operator==(const String& lhs, const String& rhs)
{
	if (lhs.size() != rhs.size() || lhs.capacity() != rhs.capacity())
		return false;
	for (auto it1 = lhs.begin(), it2 = rhs.begin(); it1 != lhs.end() && it2 != rhs.end(); ++it1, ++it2)
	{
		if (*it1 != *it2)
			return false;
	}
	return true;

}
bool operator!=(const String& lhs, const String& rhs)
{
	return !(lhs == rhs);
}

Test 14.18

strblob

bool operator<(const strblob& lhs, const strblob& rhs)
{
	return *lhs.data < *rhs.data;
}
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);
}

StrBlobPtr

bool operator<(const strblobptr& lhs, const strblobptr& rhs) {
	auto l = lhs.wptr.lock(), r = rhs.wptr.lock();
	
	if (l == r)// 若底层的 vector 是同一个
	{
		if (!r)
			return false; //如果两个指针都是空,无法比较
		return lhs.curr < rhs.curr;//lhs指向的元素在rhs指向的元素前面时返回true
	}	
	else
		return false;       // 若指向不同 vector,则无法比较

}

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)
{
	if (lhs.size() < rhs.size())
		return true;
	else if (lhs.size() == rhs.size())
	{
		for (auto it1 = lhs.begin(), it2 = rhs.begin(); it1 != lhs.end() && it2 != rhs.end(); ++it1, ++it2)
		{
			if (*it1 >= *it2)
				return false;
		}
	}
	else
		return false;

	return true;
}
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 String& lhs, const String& rhs)
{
	if (lhs.size() < rhs.size())
		return true;
	else if (lhs.size() == rhs.size())
	{
		for (auto it1 = lhs.begin(), it2 = rhs.begin(); it1 != lhs.end() && it2 != rhs.end(); ++it1, ++it2)
		{
			if (*it1 >= *it2)
				return false;
		}
	}
	else
		return false;

	return true;
}
bool operator>(const String& lhs, const String& rhs)
{
	return rhs < lhs;
}
bool operator<=(const String& lhs, const String& rhs)
{
	return !(lhs > rhs);
}
bool operator>=(const String& lhs, const String& rhs)
{
	return !(lhs < rhs);
}

Test 14.22

my_sales_data& my_sales_data::operator=(const std::string& isbn)
{
	bookNo = isbn;
	return *this;
}

Test 14.23

StrVec& StrVec::operator=(initializer_list<string> il)
{
	//alloc_n_copy分配新内存空间并拷贝元素
	auto data = alloc_n_copy(il.begin(), il.end());
	free();
	//更新指针
	elements = data.first;
	first_free = cap = data.second;
	return *this;
}

Test 14.26

StrVec

class StrVec
{
    string& operator[](size_t n) { return *(elements +n); };
    const string& operator[](size_t n) const { return *(elements + n); };
}

String

class String
{
    char& operator[](size_t n) { return *(elements + n); };
    const char& operator[](size_t n) const { return *(elements + n); };
}

strblob

class strblob
{
	string& operator[](size_t n) { check(n, "out of range"); return (*data)[n]; }
	const string& operator[](size_t n) const { check(n, "out of range"); return (*data)[n]; }
}

strblobptr

class strblobptr
{
    string& operator[](size_t n) { auto p = check(n, "out of range"); return (*p)[n]; }
	const string& operator[](size_t n) const { auto p = check(n, "out of range"); return (*p)[n]; }
}

Test 14.27-14.28

strblobptr.h

class strblobptr
{
	friend strblobptr operator+(strblobptr&, size_t n);
	friend strblobptr operator-(strblobptr&, size_t n);

public:
	strblobptr& operator++();
	strblobptr& operator--();
	strblobptr operator++(int);
	strblobptr operator--(int);
	strblobptr& operator+=(size_t n);
	strblobptr& operator-=(size_t n);

private:
	shared_ptr<vector<string>> check(size_t, const string&) const;
	weak_ptr<vector<string>> wptr;
	size_t curr;
};

strblobptr.cpp

strblobptr& strblobptr::operator++()
{
	check(curr, "increment past end of strblobptr"); //如果已经指向了尾后位置,则无法递增
	++curr;
	return *this;
}
strblobptr& strblobptr::operator--()
{
	--curr;
	check(curr, "decrement past begin of strblob");
	return *this;
}

strblobptr strblobptr::operator++(int)
{
	strblobptr ret = *this;
	++(*this);
	return ret;
}

strblobptr strblobptr::operator--(int)
{
	strblobptr ret = *this;
	--(*this);
	return ret;
}

strblobptr& strblobptr::operator+=(size_t n)
{
	check(curr + n, "increment past end of strblobptr");
	curr += n;
	return *this;
}
strblobptr& strblobptr::operator-=(size_t n)
{
	curr -= n;
	check(curr, "decrement past begin of strblob");
	return *this;
}

strblobptr operator+(strblobptr& lhs, size_t n)
{
	return lhs += n;
}
strblobptr operator-(strblobptr& lhs, size_t n)
{
	return lhs -= n;
}

Test 14.32

class ToPtr {
public:
    ToPtr() = default;
    ToPtr(strblobptr* p) : pointer(p) {}

    strblobptr& operator*() { return *this->pointer; };
    strblobptr* operator->() { return &this->operator*(); };

private:
    strblobptr* pointer = nullptr;
};

int main() {
    strblob a1 = { "hi", "bye", "now" };
    strblobptr p1(a1);               // p1 指向 a1 中的 vector
    ToPtr p(&p1);
    cout << p->operator->()->front();
    cout << p->operator->()->back() << endl;

    return 0;
}

Test 14.34

class ifelse
{
public:
    ifelse() = default;
    int operator()(bool state, int b, int c) {
        if (state)
            return b;
        else
            return c;
    }
};

Test 14.35

class printstr
{
public:
    printstr(istream& i = cin, ostream& o = cout) :is(i), os(o) {};
    string operator()() { return (getline(is, str) ? str : " "); };
private:
    istream& is;
    ostream& os;
    string str;
};

int main()
{
    ifstream fin("infile.txt");
    printstr obj(fin);
    cout << obj();

    return 0;
}

Test 14.36

int main()
{
    ifstream fin("infile.txt");
    printstr obj(fin);
    vector<string> svec;
            
    string s = obj();
    while (s != " ")
    {
        svec.push_back(s);
        s = obj();
    }

    for (auto& s : svec)
        cout << s << endl;


    return 0;
}

Test 14.37

class checkequal
{
public:
    checkequal(const char& l) :a(l) {};
    bool operator()(const char& b) { return a == b; }

private:
    char a;
};

int main()
{
    string str("abcdabcdabcd");
    for (auto& c : str)
    {
        checkequal obj('c');
        replace_if(str.begin(), str.end(), obj, 'C');
    }

    for (auto& c : str)
        cout << c;
    cout << endl;

    return 0;
}

Test 14.38

class checksize
{
public:
    checksize(const string& s) : str(s) {};
    int operator()() { return str.size(); };
private:
    string str;
};

int main()
{
    ifstream fin("infile.txt");
    string s;
    map<int, int> counts;
    while (fin >> s)
    {
        checksize size(s);
        ++counts[size()];
    }

    for (auto& p : counts)
        cout << p.first << " occurs: " << p.second << endl;
        
    return 0;
}

Test 14.39

int main()
{
    ifstream fin("infile.txt");
    string s;
    map<int, int> counts;

    int short_word = 0;
    int long_word = 0;
    while (fin >> s)
    {
        checksize size(s);
        size() > 9 ? ++long_word : ++short_word;
    }
    cout << "short word : " << short_word << endl;
    cout << "long word : " << long_word << endl;
        
    return 0;
}

Test 14.40

class comparestr
{
public:
    bool operator()(const string& s1, const string& s2) { return s1.size() < s2.size(); };
};

class comparesz
{
public:
    comparesz(const vector<string>::size_type& s) : sz(s) {};
    bool operator()(const string& s1) { return s1.size() >= sz; };
private:
    vector<string>::size_type sz;
};

void bigges(vector<string>& words, vector<string>::size_type& sz)
{
    elimDups(words);
    stable_sort(words.begin(), words.end(), [](const string& s1, const string& s2) {return s1.size() < s2.size(); });
    auto it = find_if(words.begin(), words.end(), [sz](const string& s1) {return s1.size() >= sz; });
    auto cnt = words.end() - it;

    cout << cnt << (cnt > 1 ? " words" : " word") << " of length " << sz << " or longer" << endl;
    for_each(it, words.end(), [](const string& s) {cout << s << " "; }); cout << endl;

}

Test 14.42


int main()
{
    using std::placeholders::_1;

    vector<int> ivec{ 1001, 2001, 1002, 3002, 4396 };
    vector<string> svec{ "pooh", "pooh", "pooh", "wg", "hs" };

    cout << count_if(ivec.begin(), ivec.end(), bind(greater<int>(), _1, 1024)) << endl;
    cout << *find_if(svec.begin(), svec.end(), bind(not_equal_to<string>(), _1, "pooh")) << endl;

    multiplies<int> mulit;
    for (auto& i : ivec)
        i = mulit(i, 2);
    for (auto& i : ivec)
        cout << i << endl;

    return 0;
}

Test 14.43

bool calmodulus(const int& ival, const vector<int>& ivec)
{
    modulus<int> intMod;
    for (auto& i : ivec)
        if (intMod(ival, i) != 0)
            return false;
    return true;
}

Test 14.44

int add(int i, int j)
{
    return i + j;
}

auto mod = [](int i, int j) {return i % j; };

struct divide
{
    int operator()(int i, int j) { return i / j; };
};

int main()
{
    map<string, function<int(int, int)>> binops = {
        {"+", add},
        {"-", std::minus<int>()},
        {"*", [](int i, int j) {return i * j; }},
        {"/", divide()},
        {"%", mod}
    };

    return 0;
}

Test 14.45

class my_sales_data
{
public:
	explicit operator std::string() const { return bookNo; };
	explicit operator double() const { return revenue; };
private:
	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
};

Test 14.53

class SmallInt
{
    friend SmallInt operator+(const SmallInt&, const SmallInt&);
public:
    SmallInt(int = 0);
    operator int() const {
        return val;
    };

private:
    size_t val;
};

int main()
{
    SmallInt s1;
    double d = s1 + SmallInt(3.14);

    return 0;
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值