赞
踩
#include <iostream> #include <string> struct Sales_data { std::string bookNo; unsigned units_sold = 0; double revenue = 0.0; }; 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.bookNo == trans.bookNo) { total.units_sold += trans.units_sold; total.revenue += trans.revenue; } 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.bookNo = trans.bookNo; total.units_sold = trans.units_sold; total.revenue = trans.revenue; } } 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 } }
#ifndef SALES_DATA_H #define SALES_DATA_H #include<string> struct Sale_data { std::string bookNo; unsigned units_sold = 0; double revenue = 0.0; 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
#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 } }
#ifndef PERSON_H_
#define PERSON_H_
#include <string>
struct Persson
{
std::string person;
std::string address;
};
#endif
应该是const,因为只需要读取成员对象,无需改变
ifndef PERSON_H_
#define PERSON_H_
#include <string>
struct Persson
{
std::string name;
std::string address;
std::string get_name() const{return name};
std::string get_address() const{return address};
};
#endif
#ifndef SALES_DATA_H_ #define SALES_DATA_H_ #include <string> struct Sales_data { std::string bookNo; unsigned units_sold = 0; double revenue = 0.0; std::string isbn() const { return bookNo; } Sales_data& combine(const Sales_data&); double avg_price()const; }; 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; retuen is; } std::ostream &print(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
#include <iostream> #include <string> #include "Sales_data.h" int main() { Sales_data total; 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 } }
read需要改变成员对象;
print只需要读取成员对象。
ifndef PERSON_H_ #define PERSON_H_ #include <string> struct Persson { std::string name; std::string address; std::string get_name() const{return name}; std::string get_address() const{return address}; }; std::istream &read(istream &is, Person &item) { return is>>item.name>>" ">>item.address; } std::ostream &print(ostream &os, Person &item) { return os<<item.name<<" "<<item.address; } #endif
读入data1和data2并判断是否为真
Sales_data_ex11.h
#ifndef SALES_DATA_H_ #define SALES_DATA_H_ #include <string> 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.0; std::string isbn() const {return bookNo;} Sales_data& combine(const Sales_data&); double avg_price() const; }; 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; } Sales_data::Sales_data(std::istream &) { return (is,*this); } Sales_data& Sales_data::combine(const Sales_data&rhs) { units_sold+=rhs.units_sold; revenue+=rhs.revenue; return *this; } #endif
ex11.cpp
#include <string> #include <iostream> #include "Sales_data.h" int main() { Sales_data sales_data1; print(std::cout, sales_data1) << std::endl; Sales_data sales_data2("1-01"); print(std::cout, sales_data2) << std::endl; Sales_data sales_data3("1-01", 1, 100); print(std::cout, sales_data3) << std::endl; Sales_data sales_data4(std::cin); print(std::cout, sales_data4) << std::endl; // Sales_data sales_data5(); // print(std::cout, sales_data5) << std::endl; return 0; }
Sales_data_ex12.h
#ifndef SALES_DATA_H_ #define SALES_DATA_H_ #include <string> 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
ex12.cpp
#include <string> #include <iostream> #include "Sales_data_ex12.h" int main() { Sales_data sales_data1; print(std::cout, sales_data1) << std::endl; Sales_data sales_data2("1-01"); print(std::cout, sales_data2) << std::endl; Sales_data sales_data3("1-01", 1, 100); print(std::cout, sales_data3) << std::endl; Sales_data sales_data4(std::cin); print(std::cout, sales_data4) << std::endl; // Sales_data sales_data5(); // print(std::cout, sales_data5) << std::endl; return 0; }
Sales_data():bookNo(""),units_sold(0),revenue(0){}
ifndef PERSON_H_ #define PERSON_H_ #include <string> struct Person; std::istream &read(std::istream &is,Person &item); std::ostream &print(std::ostream &os,Person &item); struct Persson { std::string name; std::string address; std::string get_name() const{return name}; std::string get_address() const{return address}; }; std::istream &read(istream &is, Person &item) { return is>>item.name>>" ">>item.address; } std::ostream &print(ostream &os, Person &item) { return os<<item.name<<" "<<item.address; } #endif
一个类可以包含0个或多个访问说明符,而且对于某个访问说明符能出现多少次也没有严格规定;
public:成员在整个程序内可以被访问;
private:成员可以被类的成员函数访问,但是不能被使用该类的代码访问.
struct 的默认访问权限是public
class 的默认访问权限是private
封装实现了接口与实现的分离,隐藏了类型的实现细节,在c++中通过将实现放在一个类的私有部分实现的;
优点
1.确保用户不会无意间破坏封装对象的状态
2.被封装的类的具体实现细节可以随时改变,而无需调整用户级别的代码。
struct Person
{
public:
Person() : name(""), address(""){}
Person(const std::string &sname, const std::string &saddress = "") : name(sname), address(saddress){}
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。用户可以调用接口,而无法改变成员属性。
类允许其他类或者函数访问它的非公有成员,方法是其他类或者函数成为它的友元。
优点:
外部函数方便使用类的成员,而不需要显式加上类名;
可以方便访问所有非公有成员;
有时,对类的用户更容易读懂。
缺点:
减少封装性和可维护性;
代码冗长,类内的声明,类外函数的声明。
Sale_data_ex21.h
#ifndef SALES_DATA_H_ #define SALES_DATA_H_ #include <string> 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
ex21.cpp
#include <iostream> #include <string> #include "Sales_data_ex21.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 } }
#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 &sname, const std::string &saddress = "") : name(sname), address(saddress){} 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
ex22.cpp
#include <string> #include <iostream> #include "Person_ex22.h" int main() { Person person1; print(std::cout, person1) << std::endl; Person person2("tx", "shenzhen"); print(std::cout, person2) << std::endl; std::cout << person2.get_name() << " " << person2.get_address() << std::endl; Person person3("tx"); print(std::cout, person3) << std::endl; Person person4(std::cin); print(std::cout, person4) << std::endl; return 0; }
#ifndef SCREEN.H #define SCREEN.H #include<string> class Screan { public: typedef std::string::size_type pos; Screan() = default; Screan(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]; } private: pos cursor; pos height = 0, width = 0; std::string contents; }; #endif // !SCREEN.H
#ifndef SCREEN.H #define SCREEN.H #include<string> class Screan { public: typedef std::string::size_type pos; Screan() = default; Screan(pos ht, pos wd) :height(ht), width(wd){} Screan(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]; } private: pos cursor; pos height = 0, width = 0; std::string contents; }; #endif // !SCREEN.H
能,Screen类中只有string和内置类型可以使用拷贝和赋值操作;
Sales_data_ex26.h
#ifndef SALES_DATA_H_ #define SALES_DATA_H_ #include <string> 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&); private: inline 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; } 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
ex26.cpp
#include <iostream> #include <string> #include "Sales_data_ex26.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 } }
ex27.h
#ifndef SCREEN_H_ #define SCREEN_H_ #include<string> class Screen { public: typedef std::string::size_type pos; 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; } private: pos cursor; 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; } #endif // !SCREEN.H
ex27.cpp
#include <string> #include <iostream> #include "ex27.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; }
返回类型是Screen&的输出:
XXXXXXXXXXXXXXXXXXXX#XXXX
XXXXXXXXXXXXXXXXXXXX#XXXX
返回类型是Screen的输出:
XXXXXXXXXXXXXXXXXXXX#XXXX
XXXXXXXXXXXXXXXXXXXXXXXXX
因为这样的话move、set和display返回的是Screen的临时副本,后续set和display操作并不会改变myScreen
正确
返回类型是Screen的输出:
XXXXXXXXXXXXXXXXXXXX#XXXX
XXXXXXXXXXXXXXXXXXXXXXXXX
优点:更加明确,减少误读可能性;
void setAddr(const std::string &addr){this->addr=addr;}
缺点:代码冗余
std::string getAddr()const {return this->addr;}
#ifndef ex_31_h
#define ex_31_h
class Y;
class X{Y *y=nullptr;};
class Y{X x;};
#endif
#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
ex27.h
#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: typedef std::string::size_type pos; 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; }; pos size()const; private: pos cursor; 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; } Screen::pos Screen::size()const { return height * width; } void Window_mgr::clear(ScreenIndex i) { Screen& s = screens[i]; s.contents = std::string(s.height * s.width, ' '); } #endif // !SCREEN.H
test.cpp
#include <string> #include <iostream> #include "ex27.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"; std::cout << myScreen.size() << std::endl; return 0; }
dummy_fcn(pos height)中的pos未声明,报错;
typedef string Type; Type initVal(); // use `string` class Exercise { public: typedef double Type; Type setVal(Type); // use `double` Type initVal(); // use `double` private: int val; }; Type Exercise::setVal(Type parm) { // first is `string`, second is `double` val = parm + initVal(); // Exercise::initVal() return val; }
修改为
Exercise::Type Exercise::setVal(Type parm) { // first is `string`, second is `double`
val = parm + initVal(); // Exercise::initVal()
return val;
成员初始化顺序和类中定义的顺序一致,故先初始化rem,后初始化base,初始化rem需要用到base,故程序报错;
改为:
struct X {
X (int i, int j): base(i), rem(base % j) {}
int rem, base;
};
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
}
Sales_data(std::istream &is=std::cin){read(is,*this);}
非法,重载Sale_data()将不明确;
#include <string> #include <iostream> using std::string; class Book { public: Book(unsigned isbn, string const& name, string const& author, string const& pubdate) :isbn_(isbn),name_(name),author_(author),pubdate_(pubdate) {} explicit Book(std::istream& in) { in >> isbn_ >> name_ >> author_ >> pubdate_; } private: unsigned isbn_; string name_; string author_; string pubdate_; };
Sales_data_ex41.h
#ifndef SALES_DATA_H_ #define SALES_DATA_H_ #include <string> 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 << "Sales_data(const std::string &s, unsigned n, double p)" << std::endl;} Sales_data() : Sales_data("", 0, 0){std::cout << "Sales_data() : Sales_data(\"\", 0, 0)" << std::endl;} Sales_data(const std::string &s) : Sales_data(s, 0, 0){std::cout << "Sales_data(const std::string &s) : Sales_data" << std::endl;} Sales_data(std::istream &is) : Sales_data(){read(is, *this);std::cout << "Sales_data(std::istream &is) : Sales_data()" << std::endl;} std::string isbn() const {return bookNo;} Sales_data& combine(const Sales_data&); private: inline 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; } 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
ex41.cpp
#include <iostream>
#include <string>
#include "Sales_data_ex41.h"
int main()
{
Sales_data sales_data1("001-01", 1, 100);
Sales_data sales_data2;
Sales_data sales_data3("001-02");
Sales_data sales_data4(std::cin);
return 0;
}
#include <string> #include <iostream> using std::string; class Book { public: Book(unsigned isbn, string const& name, string const& author, string const& pubdate) :isbn_(isbn),name_(name),author_(author),pubdate_(pubdate) {} explicit Book(std::istream& in) { in >> isbn_ >> name_ >> author_ >> pubdate_; } private: unsigned isbn_; string name_; string author_; string pubdate_; };
class NoDefault
{
public:
NoDefault(int i) {}
};
class C
{
public:
C() :def(0) {} //define the constructor of C.
private:
NoDefault def;
};
非法,NoDefault没有默认构造函数;
合法,C中有默认构造函数;
a)不正确,没有构造函数时,有时可以生成默认构造函数;
b)不正确,默认构造函数是没有构造函数的情况下,由编译器生成的构造函数;
c)不正确,默认构造函数在一定情况下十分重要;
d)不正确,当类没有显式定义构造函数时,编译器才会隐式定义默认构造函数;
优点:
防止隐式类型转换;
可以只用作初始化;
缺点:
只有单参数的构造函数才有意义;
都不会有问题;
a)正确;
b)combine的参数时非常量的引用,我们不能将临时参数传递给它,改为:
Sales_data &combine(const Sales_data&);
c) 不正确,后面的const不对,this需要可改变;
#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 &sname, const std::string &saddress = "") : name(sname), address(saddress){} explicit 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
以下函数
int getSize(const std::vector<int> &);
getSize(34);
如果vector的构造函数没有explicit,我们就不会明白上述函数的意思;
string就不同,下面的函数我们就很清楚;
void setName(std::string);
setYourName("peay");
改初始化使用花括号括起来的初始化列表来初始化聚合类数据成员。所以我们要定义聚合类
struct Sales_data {
std::string bookNo;
unsigned units_sold;
double revenue;
};
#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) { hw = b; } private: bool hw; bool io; bool other; }; #endif // !DEBUG_EX53_
在c++11中,constexpr函数不能改变数据成员,c++14中没有这个特点;
不是。std::string 不是字面值类型;
#include <string> #include <iostream> #include <type_traits> struct Data { int ival; std::string s; }; int main() { std::cout << std::boolalpha; std::cout << std::is_literal_type<Data>::value << std::endl; // output: false }
类的静态成员与类本身直接相关,而不是与类的各个对象相互关联;
每个对象不需要存储公共数据,如果数据被改变,则每个对象都可以使用新值;
静态数据成员可以是不完全型;
可以使用静态成员作为默认实参;
#ifndef ACCOUNT_EX57_H_ #define ACCOUNT_EX57_H_ #include<string> class Account { void calculate() { amount += amount * interestRate; } static double rate() { return interestRate; } static void rate(double); private: std::string owner; double amount; static double interestRate; static double initRate(); }; double Account::interestRate = initRate(); #endif // !ACCOUNT_EX57_H_
//example.h
class Example {
public:
static double rate ;
static const int vecSize = 20;
static vector<double> vec;
};
//example.c
#include "example.h"
double Example::rate=6.5;
vector<double> Example::vec(vecSize);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。