C++primer_calss类

df# 学习目标:
掌握类的基础内容

学习内容:

1.类的简介
2.自定义数据结构
3.定义抽象数据类型
4.访问控制与封装
5.类的其他特性
6.类的作用域
7.构造函数再探
8.类的静态成员

题目解析

1.20

#include <iostream>
#include "Sales_item.h"

int main()
{
	Sales_item sa;
	std::cin >> sa;
	std::cout << sa << std::endl;
}

1.21

#include <iostream>
#include "Sales_item.h"

int main()
{
	Sales_item sa1;
	Sales_item sa2;
	std::cin >> sa1 >> sa2;
	std::cout << sa1 + sa2 << std::endl;
}

1.22

#include <iostream>
#include "Sales_item.h"

int main()
{
	Sales_item sa1;
	Sales_item sum_sa2;
	std::cin >> sum_sa2;
	while (std::cin >> sa1)
		sum_sa2 += sa1;
	std::cout << sum_sa2 << std::endl;
}

1.23

#include <iostream>
#include "Sales_item.h"

int main()
{
    Sales_item currItem, valItem;
    if (std::cin >> currItem) {
        int cnt = 1;
        while (std::cin >> valItem) {
            if (valItem.isbn() == currItem.isbn())
                ++cnt;
            else {
                std::cout << currItem << " occurs " << cnt << " times "
                          << std::endl;
                currItem = valItem;
                cnt = 1;
            }
        }

        std::cout << currItem << " occurs " << cnt << " times " << std::endl;
    }
    return 0;
}

1.24
测试

2.39
“foo”后面接“int”是非法的(是否忘记了“;”?)
main”的返回类型应为“int”而非“foo”
return”: 无法从“int”转换为“foo”

2.40

struct foo {
	std::string ib;
	unsigned com = 0;
	double pre = 0.00;
};

2.41

#include <iostream>
#include <string>
#include "Sales_data.h"
int main()
{
	Sales_data data1, data2;
	double price = 0;
	std::cin >> data1.bookno >> data1.units_sold >> price;
	data1.revenue = data1.units_sold * price;
	std::cin >> data2.bookno >> data2.units_sold >> price;
	data2.revenue = data2.units_sold * price;
	if (data1.bookno == data2.bookno) {
		unsigned totalCnt = data1.units_sold + data2.units_sold;
		double totalRevenue = data1.revenue + data2.revenue;
		std::cout << data1.bookno << " " << totalCnt << " "
			<< totalRevenue << " ";
		if (totalRevenue != 0)
			std::cout << totalRevenue/totalCnt << std::endl;
		else
			std::cout << "没有售出书本" << std::endl;
		return 0;
	}
	else {
		std::cerr << "不是相同书目" << std::endl;
		return -1;
	}
}
#include <iostream>
#include <string>
#include "Sales_data.h"

using std::cin;

int main()
{
	Sales_data data1, data2;
	double price1 = 0;
	if (cin >> data1.bookno >> data1.units_sold >> price1)
		data1.revenue = data1.units_sold * price1;
	double price2 = 0;
	while (cin >> data2.bookno >> data2.units_sold >> price1)
	{
		data2.revenue = data2.units_sold * price1;
		if (data1.bookno == data2.bookno)
		{
			data1.units_sold += data2.units_sold;
			data1.revenue += data2.revenue;
		}
		else
		{
			std::cout << data1.bookno << " " << data1.units_sold << " "
				<< data1.revenue << " ";
			if (data1.units_sold != 0)
				std::cout << data1.revenue / data1.units_sold << std::endl;
			else
				std::cout << "无售出";

			data1.bookno = data2.bookno;
			data1.units_sold = data2.units_sold;
			data1.revenue = data2.revenue;
		}
	}
	std::cout << data1.bookno << " " << data1.units_sold << " "
		<< data1.revenue << " ";
	if (data1.units_sold != 0)
		std::cout << data1.revenue / data1.units_sold << std::endl;
	else
		std::cout << "无售出";

	return 0;
}
	

2.42

#pragma once
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
struct Sales_data {
	std::string bookno;
	unsigned units_sold = 0;
	double revenue = 0.00;
};

#endif

与41题相似

7.1
见习题2.41

7.2

#pragma once
#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <string>
#include <iostream>

struct Sales_data {
	std::string bookno;
	unsigned units_sold = 0;
	double revenue = 0.00;

	std::string isbn() const { return bookno; }
	Sales_data &combine(const Sales_data &);
};
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.revenue;
	return *this;
}

#endif

7.3

#include <iostream>
#include <string>
#include "Sales_data.h"

int main()
{
    Sales_data total;
    double totalPrice;

    if (std::cin >> total.bookNo >> total.units_sold >> totalPrice)
    {
        total.revenue = total.units_sold * totalPrice;

        Sales_data trans;
        double transPrice;
        while (std::cin >> trans.bookNo >> trans.units_sold >> transPrice)
        {
            trans.revenue = trans.units_sold * transPrice;

            if (total.isbn() == trans.isbn())
            {
                total.combine(trans);
            }
            else
            {
                std::cout << total.bookNo << " " << total.units_sold << " " << total.revenue << " ";
                if (total.units_sold != 0)
                    std::cout << total.revenue / total.units_sold << std::endl;
                else
                    std::cout << "(no sales)" << std::endl;

                total = trans;
            }
        }

        std::cout << total.bookNo << " " << total.units_sold << " " << total.revenue << " ";
        if (total.units_sold != 0)
            std::cout << total.revenue / total.units_sold << std::endl;
        else
            std::cout << "(no sales)" << std::endl;

        return 0;
    }
    else
    {
        std::cerr << "No data?!" << std::endl;
        return -1;  // indicate failure
    }
}

7.4

#pragma once
#ifndef PERSON_H
#define PERSON_H

#include <string>

struct Person {
	std::string name;
	std::string address;
};

#endif

7.5
使用const,只需读取成员函数的成员对象无需改变对象

#pragma once
#ifndef PERSON_H
#define PERSON_H

#include <string>

struct Person {
	std::string name;
	std::string address;

	std::string get_name() const { return name; }
	std::string get_address() const { return address; }
};

#endif

7.6

#pragma once
#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <string>
#include <iostream>

struct Sales_data {
	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.00;

	std::string isbn() const { return bookNo; }
	Sales_data &combine(const Sales_data &);
	double avg_price() const;
};
double Sales_data::avg_price() const {
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.revenue;
	return *this;
}
std::istream &read(std::istream &is, Sales_data &item)
{
	double price = 0;
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = price * item.units_sold;
	return is;
}
std::ostream &print(std::ostream &os, const Sales_data &item)
{
	os << item.isbn() << " " << item.units_sold << " "
		<< item.revenue << " " << item.avg_price();
	return os;
}
Sales_data add(const Sales_data &lsh, const Sales_data &rhs)
{
	Sales_data sum = lsh;
	sum.combine(rhs);
		return sum;
}

#endif

7.7

#include <iostream>
#include <string>
#include "Sales_data.h"

int main()
{
    Sales_data total;
    double totalPrice;

    if (read(std::cin, total))
    {

        Sales_data trans;
       while (read(std::cin, trans))
        {

            if (total.isbn() == trans.isbn())
            {
                total.combine(trans);
            }
            else
            {
                print(std::cout, total);
                std::cout << std::endl;
                total = trans;
            }
        }

        print(std::cout, total);
        std::cout << std::endl;

        return 0;
    }
    else
    {
        std::cerr << "No data?!" << std::endl;
        return -1;  // indicate failure
    }
}

7.8
read的Sales_data参数会被修改,print不会

7.9

#pragma once
#ifndef PERSON_H
#define PERSON_H

#include <string>

struct Person {
	std::string name;
	std::string address;

	std::string get_name() const { return name; }
	std::string get_address() const { return address; }
};
std::istream &read(std::istream &is, Person &item)
{
	return is >> item.name >> item.address;
}
std::ostream &print(std::ostream &os, const Person &item)
{
	return os << item.name << " " << item.address;
}

#endif

7.10
输入data1和data2,判断条件是否为真

7.11

#pragma once
#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <string>
#include <iostream>

struct Sales_data {
	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(p*n) { }
	Sales_data(std::istream &);

	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.00;

	std::string isbn() const { return bookNo; }
	Sales_data &combine(const Sales_data &);
	double avg_price() const;
};
double Sales_data::avg_price() const {
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.revenue;
	return *this;
}
std::istream &read(std::istream &is, Sales_data &item)
{
	double price = 0;
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = price * item.units_sold;
	return is;
}
std::ostream &print(std::ostream &os, const Sales_data &item)
{
	os << item.isbn() << " " << item.units_sold << " "
		<< item.revenue << " " << item.avg_price();
	return os;
}
Sales_data add(const Sales_data &lsh, const Sales_data &rhs)
{
	Sales_data sum = lsh;
	sum.combine(rhs);
		return sum;
}

#endif

7.12

#pragma once
#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <string>
#include <iostream>

struct Sales_data;

std::istream &read(std::istream &is, Sales_data &item);
std::ostream &print(std::ostream &os, const Sales_data &item);
Sales_data add(const Sales_data &lhs, const Sales_data &rhs);


struct Sales_data 
{
	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(p*n) {}
	Sales_data(std::istream &is) {read(is,*this); }

	std::string isbn() const { return bookNo; }
	Sales_data &combine(const Sales_data &);
	double avg_price() const;

	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
};

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

double Sales_data::avg_price() const {
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}

std::istream &read(std::istream &is, Sales_data &item)
{
	double price = 0;
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = price * item.units_sold;
	return is;
}
std::ostream &print(std::ostream &os, const Sales_data &item)
{
	os << item.isbn() << " " << item.units_sold << " "
		<< item.revenue << " " << item.avg_price();
	return os;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
	Sales_data sum = lhs;
	sum.combine(rhs);
		return sum;
}

#endif

7.13

#include <iostream>
#include <string>
#include "Sales_data.h"

int main()
{
    Sales_data total (std::cin);

    if (!total.isbn().empty())
    {

        Sales_data trans;
       while (read(std::cin, trans))
        {

            if (total.isbn() == trans.isbn())
            {
                total.combine(trans);
            }
            else
            {
                print(std::cout, total);
                std::cout << std::endl;
                total = trans;
            }
        }

        print(std::cout, total);
        std::cout << std::endl;
        return 0;
    }
    else
    {
        std::cerr << "No data?!" << std::endl;
        return -1;  // indicate failure
    }
}

7.14

	Sales_data() : bookNo(""), units_sold(0), revenue(0){}

7.15

#pragma once
#ifndef PERSON_H
#define PERSON_H

#include <string>

struct Person;
std::istream &read(std::istream &is, Person &item);
std::ostream &print(std::ostream &os, const Person &item);

struct Person {

	Person() : name(" "), address(" "){}
	Person (const std::string &n, const std::string &a) : name(n), address(a){}
	Person(std::istream &is) { read(is, *this); }

	std::string name;
	std::string address;

	std::string get_name() const { return name; }
	std::string get_address() const { return address; }
};
std::istream &read(std::istream &is, Person &item)
{
	return is >> item.name >> item.address;
}
std::ostream &print(std::ostream &os, const Person &item)
{
	return os << item.name << item.address;
}

#endif

7.16
一个类可以包含0个或多个访问说明符,而且对于某个说明符能出现多少次也没有严格的限定
public成员定义类接口,private部分封装了类的实现部分。

7.17
使用struct关键字,则定义在第一个访问说明符之前的成员是public的,
相反,使用class关键字,则这些成员是private的。

7.18
含义:封装实现了类的接口和实现的分离
用处:1.确保用户代码不会无意间破坏封装对象的状态。2.被封装的类的具体实现细节可以随时改变,
而无须调整用户级别的代码。

7.19

struct Person {

public:
	Person() : name(" "), address(" "){}
	Person (const std::string &n, const std::string &a) : name(n), address(a){}
	Person(std::istream &is) { read(is, *this); }

	std::string get_name() const { return name; }
	std::string get_address() const { return address; }

private:
	std::string name;
	std::string address;
};

接口应该是公共的所以使用public,实现的部分比如数据不应该暴露在外所以使用private。

7.20
使其允许其他类或函数访问它的非公有成员
优点:
外部函数可以方便地使用类的成员,而不需要显示地给它们加上类名;
可以方便地访问所有非公有成员;
有时,对类的用户更容易读懂。
缺点:
减少封装和可维护性;
代码冗长,类内的声明,类外函数声明。

7.21

#pragma once
#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <string>
#include <iostream>

struct Sales_data;

std::istream &read(std::istream &is, Sales_data &item);
std::ostream &print(std::ostream &os, const Sales_data &item);
Sales_data add(const Sales_data &lhs, const Sales_data &rhs);


struct Sales_data 
{
	friend std::istream &read(std::istream &is, Sales_data &item);
	friend std::ostream &print(std::ostream &os, const Sales_data &item);
	friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs);

public:
	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(p*n) {}
	Sales_data(std::istream &is) {read(is,*this); }

	std::string isbn() const { return bookNo; }
	Sales_data &combine(const Sales_data &);
	double avg_price() const;

private:
	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
};

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

double Sales_data::avg_price() const {
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}

std::istream &read(std::istream &is, Sales_data &item)
{
	double price = 0;
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = price * item.units_sold;
	return is;
}
std::ostream &print(std::ostream &os, const Sales_data &item)
{
	os << item.isbn() << " " << item.units_sold << " "
		<< item.revenue << " " << item.avg_price();
	return os;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
	Sales_data sum = lhs;
	sum.combine(rhs);
		return sum;
}

#endif

7.22

#pragma once
#ifndef PERSON_H
#define PERSON_H

#include <string>

struct Person;
std::istream &read(std::istream &is, Person &item);
std::ostream &print(std::ostream &os, const Person &item);

struct Person {
	friend std::istream &read(std::istream &is, Person &item);
	friend std::ostream &print(std::ostream &os, const Person &item);

public:
	Person() : name(" "), address(" "){}
	Person (const std::string &n, const std::string &a) : name(n), address(a){}
	Person(std::istream &is) { read(is, *this); }

	std::string get_name() const { return name; }
	std::string get_address() const { return address; }

private:
	std::string name;
	std::string address;
};
std::istream &read(std::istream &is, Person &item)
{
	return is >> item.name >> item.address;
}
std::ostream &print(std::ostream &os, const Person &item)
{
	return os << item.name << item.address;
}

#endif

7.23

#pragma once
#ifndef SCREEN_H
#define SCREEN_H

#include <iostream>
#include <string>

class Screen {
public:
	typedef std::string::size_type pos;
	Screen() = default;

	Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c){}
	char get() const { return contents[cursor]; }
	inline char get(pos ht, pos wd) const;
	Screen &move(pos r, pos c);
private:
	pos cursor = 0;
	pos height = 0, width = 0;
	std::string contents;
};

inline Screen &Screen::move(pos r, pos c)
{
	pos row = r * width;
	cursor = row + c;
	return *this;
}

char Screen::get(pos r, pos c) const
{
	pos row = r * width;
	return contents[row + c];
}
#endif

7.24

Screen() = default;
Screen(pos ht, pos wd) : height(ht), width(wd){}
Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c){}

7.25
能,Screen类中只有内置类型和string,这些能使用默认版本

7.26

//类外
inline double Sales_data::avg_price() const {
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}
//或类内显式或隐式
inline double Sales_data::avg_price() const 
double Sales_data::avg_price() const

###补充关于const的相关记忆

int i = 0; const int ci = 0;  //int const ci = 0

int &g = i; const int &g = i;  //int const &g = i; // &后面应是标识符
int &cg = ci; const int &cg = ci;

int *p = &i; const int *p = &i; // int const *p = &i;
int *cp = &ci; const int *cp = &ci;

int *const cpp = &i; const  int *const cpp = &i; // int const *const cpp = &i; // *const后面应是标识符
int *const cpp = &ci; const int *const cpp = &ci;



int i = 0;
//顶层const,不能修改地址,本身是常量
int *const p1 = &i; //
const int ci = 42;
//底层const,不能修改地址和值,本身不是常量,指向的对象是常量
//拷出的对象要是底层const,拷入的对象能转换成底层const
const int *p2 = &ci;
const int &r = ci;

7.27

#pragma once
#ifndef SCREEN_H
#define SCREEN_H

#include <iostream>
#include <string>

class Screen {
public:
	typedef std::string::size_type pos;
	Screen &set(char);
	Screen &set(pos, pos, char);
	Screen() = default;

	Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht * wd, c){}
	char get() const { return contents[cursor]; }
	inline char get(pos ht, pos wd) const;
	Screen &move(pos r, pos c);
	Screen &display(std::ostream &os) { do_display(os); return *this; }
	const Screen &display(std::ostream &os) const { do_display(os); return *this; }

private:
	pos cursor = 0;
	pos height = 0, width = 0; 
	std::string contents;
	void do_display(std::ostream &os) const { os << contents; }
};

inline Screen &Screen::move(pos r, pos c)
{
	pos row = r * width;
	cursor = row + c;
	return *this;
}

char Screen::get(pos r, pos c) const
{
	pos row = r * width;
	return contents[row + c];
}
inline Screen &Screen::set(char c)
{
	contents[cursor] = c;
	return *this;
}
inline Screen &Screen::set(pos r, pos col, char ch)
{
	contents[r * width + col] = ch;
	return *this;
}

#endif
#include <string>
#include <iostream>
#include "SCREEN.H"

int main()
{
	Screen myScreen(5, 5, 'X');
	myScreen.move(4, 0).set('#').display(std::cout);
	std::cout << "\n";
	myScreen.display(std::cout);
	std::cout << "\n";

	return 0;
}

7.28

7.29

7.30

7.31

class X {
	Y *y = nullptr;

};

class Y {
	X x;

};

7.32

#ifndef SCREEN_H_
#define SCREEN_H_

#include <string>
#include <vector>

class Screen;

class Window_mgr
{
public:
    using ScreenIndex = std::vector<Screen>::size_type;
    void clear(ScreenIndex);
private:
    std::vector<Screen> screens;
};

class Screen 
{
friend void Window_mgr::clear(ScreenIndex);
public:
    using pos = std::string::size_type;

    Screen() = default;
    Screen(pos ht, pos wd):height(ht), width(wd){ }
    Screen(pos ht, pos wd, char c):height(ht), width(wd), contents(ht*wd, c){ }

    char get() const { return contents[cursor]; }
    char get(pos r, pos c) const { return contents[r*width+c]; }
    Screen &move(pos r, pos c);
    Screen &set(char);
    Screen &set(pos, pos, char);
    Screen &display(std::ostream &os) {do_display(os); return *this;}
    const Screen &display(std::ostream &os) const {do_display(os); return *this;}

private:
    pos cursor = 0;
    pos height = 0, width = 0;
    std::string contents;
    void do_display(std::ostream &os) const {os << contents;}
};



inline Screen &Screen::move(pos r, pos c)
{
	pos row = r * width;
	cursor = row + c;
	return *this;
}

inline Screen &Screen::set(char c)
{
	contents[cursor] = c;
	return *this;
}

inline Screen &Screen::set(pos r, pos col, char c)
{
	contents[r*width + col] = c;
	return *this;
}

void Window_mgr::clear(ScreenIndex i)
{
    Screen &s = screens[i];
    s.contents = std::string(s.height * s.width, ' ');
}

#endif

7.33

#pragma once
#ifndef SCREEN_H
#define SCREEN_H

#include <iostream>
#include <string>
#include "Window_mgr.h"


class Screen {
	friend void Window_mgr::clear(ScreenIndex);


public:
	typedef std::string::size_type pos;
	Screen &set(char);
	Screen &set(pos, pos, char);
	Screen() = default;

	Screen(pos ht, pos wd, char c) : height(ht), width(wd), contents(ht *wd, c) {}
	char get() const { return contents[cursor]; }
	inline char get(pos ht, pos wd) const;
	Screen &move(pos r, pos c);
	Screen &display(std::ostream &os) { do_display(os); return *this; }
	const Screen &display(std::ostream &os) const { do_display(os); return *this; }
	pos size() const;


private:
	pos cursor = 0;
	pos height = 0, width = 0;
	std::string contents;
	void do_display(std::ostream &os) const { os << contents; };
};

inline Screen &Screen::move(pos r, pos c)
{
	pos row = r * width;
	cursor = row + c;
	return *this;
}

char Screen::get(pos r, pos c) const
{
	pos row = r * width;
	return contents[row + c];
}
inline Screen &Screen::set(char c)
{
	contents[cursor] = c;
	return *this;
}
inline Screen &Screen::set(pos r, pos col, char ch)
{
	contents[r * width + col] = ch;
	return *this;
}
Screen::pos Screen::size() const
{
	return height * width;
}

#endif

7.34
会报错,内部声明是有顺序的

7.35

#include <string>

typedef std::string Type;
Type initVal(); // 全局的
class Exercise {
public:
    typedef double Type;
    Type setVal(Type); // 两者都是类内的
    Type initVal(); // 类内的
private:
    int val;
};
Type Exercise::setVal(Type parm) { // 前者是全局,后者是类内的
    val = parm + initVal(); // 类内的
    return val;
}
//改
//Exercise::Type Exercise::setVal(Type parm) { // 前者是全局,后者是类内的
//    val = parm + initVal();
//    return val;
//}

7.36
改变rem,base的顺序

int base,rem;

7.37

Sales_data first_item(cin);   // use Sales_data(std::istream &is) ; its value are up to your input.

int main() {
  Sales_data next;  // use Sales_data(std::string s = ""); bookNo = "", cnt = 0, revenue = 0.0
  Sales_data last("9-999-99999-9"); // use Sales_data(std::string s = ""); bookNo = "9-999-99999-9", cnt = 0, revenue = 0.0
}

7.38

Sales_data(std::istream &is = std::cin) { read(is, *this); }

7.39
非法,两个以上默认构造函数,重载构造函数不明确

7.40

#pragma once
#ifndef BOOK_H
#define BOOK_H
#include <iostream>
#include <string>

class Book
{
public:
    Book(unsigned isbn, std::string const &name, std::string const &author, std::string const &pubdate)
        :isbn_(isbn), name_(name), author_(author), pubdate_(pubdate)
    { }

    explicit Book(std::istream &in)
    {
        in >> isbn_ >> name_ >> author_ >> pubdate_;
    }

private:
    unsigned isbn_;
    std::string name_;
    std::string author_;
    std::string pubdate_;
};


#endif

7.41

#pragma once
#ifndef SALES_DATA_H
#define SALES_DATA_H

#include <string>
#include <iostream>

struct Sales_data;

std::istream &read(std::istream &is, Sales_data &item);
std::ostream &print(std::ostream &os, const Sales_data &item);
Sales_data add(const Sales_data &lhs, const Sales_data &rhs);


struct Sales_data 
{
	friend std::istream &read(std::istream &is, Sales_data &item);
	friend std::ostream &print(std::ostream &os, const Sales_data &item);
	friend Sales_data add(const Sales_data &lhs, const Sales_data &rhs);

public:
	
	Sales_data(const std::string &s, unsigned n, double p) : bookNo(s), units_sold(n), revenue(p *n) { std::cout << "s,n,p" << std::endl; }
	Sales_data(const std::string &s) : Sales_data(s, 0, 0) { std::cout << "Sales_data(s)" << std::endl; }
	Sales_data() : Sales_data("", 0, 0) { std::cout << "Sales()" << std::endl; }
	Sales_data(std::istream &is) : Sales_data() {read(is,*this); }

	std::string isbn() const { return bookNo; }
	Sales_data &combine(const Sales_data &);
	inline double avg_price() const;

private:
	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
};

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

inline double Sales_data::avg_price() const {
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}

std::istream &read(std::istream &is, Sales_data &item)
{
	double price = 0;
	is >> item.bookNo >> item.units_sold >> price;
	item.revenue = price * item.units_sold;
	return is;
}
std::ostream &print(std::ostream &os, const Sales_data &item)
{
	os << item.isbn() << " " << item.units_sold << " "
		<< item.revenue << " " << item.avg_price();
	return os;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
	Sales_data sum = lhs;
	sum.combine(rhs);
		return sum;
}

#endif

7.42

Book(unsigned isbn, std::string const &name, std::string const &author, std::string const &pubdate)
        :isbn_(isbn), name_(name), author_(author), pubdate_(pubdate)
    { }

可以作为委托构造函数,因为处理的信息量足够

7.43

#include <string>

class NoDefault {
public:
	NoDefault(int i) {};
};

	struct C {
	public:
		C() : de(0) {};

	private:
		NoDefault de;
};

7.44
合法

7.45
合法

7.46
(a)不正确,没有构造函数时,编译器会生成一个默认构造函数
(b)不正确,也有参数的默认构造函数其参数是默认值
(c)不正确,默认构造函数有时很重要
(d)不正确,当类没有显式构造函数时,编译器才会生成一个合成的默认构造函数

7.47
不是,这样方便我们进行转换
优点:
防止隐式转换的产生;
可以只用作初始化。
缺点:
只有个单个参数的构造函数才有意义。

7.48
不是explicit的:
string类型
Sales_data临时量类型
Sales_data临时量类型

是explicit
string类型
Sales_data临时量类型
Sales_data临时量类型

7.49

7.50

explicit Person(std::istream &is) { read(is, *this); }

7.51
这里直接调用参数是vector的get的一个实参数值会报错,因为函数不知道这个数是容器大小还是容器的第一个值

int get(const std::vector<int> &);
    get(12);

这里形参换成string就不会

int get2(const std::string &);
    get2("ds");

7.52
聚合类要求没有类内初始值,程序应该改成

struct Sales_data {
    std::string bookNo;
    unsigned units_sold;
    double revenue;
};

7.53

#ifndef DEBUG_EX53_
#define DEBUG_EX53_

class Debug
{
public:
	constexpr Debug(bool b = true) : hw(b), io(b), other(b) {}
	constexpr Debug(bool h, bool i, bool o) : hw(h), io(i), other(o) {}

	constexpr bool any() { return hw || io || other; }
	void set_io(bool b) { io = b; }
	void set_hw(bool b) { hw = b; }
	void set_other(bool b) { other = b; }
private:
	bool hw;
	bool io;
	bool other;
};

#endif

7.54
constexpr函数是隐式的const。

7.55
不是,有一个string类型的数据成员所以不是字面值常量类。

7.56
类的静态成员是和类绑定的成员,但是不和类的对象绑定
优点:可以直接调整对象,数据成员非法的地方静态成员可以替代
区别:数据成员的作用域在类内,静态成员的作用域在类外

7.57

#ifndef ACCOUNT_EX57_H_
#define ACCOUNT_EX57_H_

#include <string>

class Account
{
public:
	void calculate() {amount += amount * interestRate;}
	static double rate(){return interestRate;}
	static void rate(double newRate){ interestRate = newRate;}
private:
	std::string owner;
	double amount;
	static double interestRate;
	static double initRate(){return 4.0;}
};
double Account::interestRate = initRate();


#endif

7.58

//example.h
#include <vector>
class Example {
public:
    static double rate = 6.5; //成员必须为常量
    static const int vecSize = 20;
    static std::vector<double> vec(vecSize); //vecSize是在类外声明的
};
//example.c
double Example::rate;
std::vector<double> Example::vec; //静态成员只能定义一次

//example.h
#include <vector>
class Example {
public:
    static double rate;
    static const int vecSize = 20;
    static std::vector<double> vec;
};
//example.c
double Example::rate = 6.5;
std::vector<double> Example::vec(vecSize);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值