C++自修入門實境秀、C++ Primer 5版研讀秀 43/ ~v7 類別-constructors-20190907_133802





練習7.11

Sales_data.h

#pragma once

#ifndef SALES_DATA_H

#define SALES_DATA_H

#include<string>

using namespace std;//千萬不要忘了這個

struct Sales_data {

Sales_data() = default;//預設建構器(constructor)用這式會較Sales_data() {}多二個建構器,蓋=default由編譯器創建2個額外的合成的預設建構器(synthesized default constructors) 56:00

//Sales_data() :bookNo{"000-000-000" } {}

Sales_data(const string &bNo) :bookNo{bNo } {}

Sales_data(const string &bNo, const double bSize, const double rvn) :bookNo{ bNo }, bookSize{ bSize }, revenue{rvn} {}

Sales_data(const string &, const double bSize, const double, const unsigned);//在類別外定義的建構器

Sales_data(istream &);//在類別外定義的建構器

//Sales_data() {}//與Sales_data() = default;應是一樣的,然不能寫在最前面,會遮蔽後面的建構器 50:00

string bookNo;

double revenue{ 0.00 };//總營收-營業額

unsigned soldQ{ 0 };

double bookSize{0.00};

Sales_data& combine(const Sales_data&, const Sales_data&);//成員函式宣告一定要在類別內,定義可在此外

Sales_data& combine(const Sales_data&);//要改變this及其屬性值就不能再在參數列後加上const;因為加上const後this成了指向常值的常值指標,被指向的東西是不能被改變的了

string isbn()const;

double avg_price()const;

};

ostream& print(ostream& , const Sales_data&);

istream& read(istream& , Sales_data& );

Sales_data add(const Sales_data&, const Sales_data&);

#endif // !SALES_DATA_H



Sales_data.cpp:

#include "Sales_data.h"

#include<string>

#include<iostream>

using namespace std;



Sales_data::Sales_data(const string& bNo,const double bSize,const double price, const unsigned sdQ) {

bookNo = bNo; soldQ = sdQ; revenue = price * sdQ; bookSize = bSize;

}

Sales_data::Sales_data(istream& is)

{

read(is, *this);

}

Sales_data& Sales_data::combine(const Sales_data& sales_data1, const Sales_data& sales_data2)

{

this->bookNo = sales_data1.bookNo;

this->bookSize = sales_data1.bookSize;

this->soldQ = sales_data1.soldQ + sales_data2.soldQ;

this->revenue = sales_data1.revenue + sales_data2.revenue;

return *this; // TODO: insert return statement here

}

Sales_data& Sales_data::combine(const Sales_data& sales_data)

{

if (bookNo == "") bookNo = sales_data.bookNo;//因為這是Sales_data類別的成員函式,所以可以直接調用該類別內的所有成員名稱,不必全名稱

bookSize = sales_data.bookSize;

soldQ += sales_data.soldQ;

revenue += sales_data.revenue;

return *this;// TODO: insert return statement here

}

string Sales_data::isbn()const

{

return bookNo;

}



double Sales_data::avg_price()const

{

if (soldQ>0)

{

return revenue / soldQ;

}

return 0.0;

}

ostream& print(ostream& os, const Sales_data& sales_data) {

os << sales_data.isbn() << '\t' << sales_data.soldQ << '\t'

<< sales_data.revenue << '\t' << sales_data.avg_price();

return os;

}



istream& read(istream& is, Sales_data& sales_data) {//要改變引數值,參數一定要是參考,將引數用傳址(參考)方式傳遞

//decltype(cin)& read(istream is ,Sales_data sales_data) {

is >> sales_data.bookNo >> sales_data.soldQ >> sales_data.revenue;

return is;

}



Sales_data add(const Sales_data& sales_data1, const Sales_data& sales_data2)

{

Sales_data sum = sales_data1;

sum.combine(sales_data2);

return sum;

}



Run:

#include<vector>

#include "Sales_data.h"

#include <iostream>

using namespace std;

int main() {

Sales_data sd ;//和下式一樣,只是在Visual Studio預選清單中,它是從第2個建構器來讓我們選的

Sales_data sd1 = Sales_data();//可見Sales_data sd的Sales_data() 就是預設的第一個建構器

Sales_data& rSd=sd; Sales_data& rrSd=rSd;

Sales_data sd2= Sales_data(rSd);//這2個建構器是編譯器自己訂的

Sales_data sd21= Sales_data(rrSd);//這2個建構器是編譯器自己訂的

Sales_data sd3= Sales_data(cin);//這個在建構時須輸入才能執行

Sales_data sd4= Sales_data("978-986-502-172-6(平裝)");

Sales_data sd5= Sales_data("978-986-502-172-6(平裝)",24.01,310.11);

Sales_data sd6= Sales_data("978-986-502-172-6(平裝)",24.01, 110.1,3);



const vector<Sales_data> vecSd{sd,rSd,rrSd,sd1,sd2,sd21,sd3,sd4,sd5,sd6};

for (Sales_data i:vecSd)

{

print(cout,i)<<"\n"<<endl;

}

}



2:7:30



練習7.12

2:11:30



#pragma once

#ifndef SALES_DATA_H

#define SALES_DATA_H

#include<string>

using namespace std;//千萬不要忘了這個

struct Sales_data {

Sales_data() = default;//預設建構器(constructor)用這式會較Sales_data() {}多二個建構器,蓋=default由編譯器創建2個額外的合成的預設建構器(synthesized default constructors) 56:00

//Sales_data() :bookNo{"000-000-000" } {}

Sales_data(const string &bNo) :bookNo{bNo } {}

Sales_data(const string &bNo, const double bSize, const double rvn) :bookNo{ bNo }, bookSize{ bSize }, revenue{rvn} {}

Sales_data(const string &, const double bSize, const double, const unsigned);//在類別外定義的建構器

//Sales_data(istream &);//在類別外定義的建構器



2:19:59

練習7.13

3:24:00

#include "Sales_data.h"

#include <iostream>

using namespace std;

int main() {

Sales_data total=Sales_data(cin);//存放累計和的變數

//if (read(cin, total)) {//選取第一筆交易記錄

if (total.readSeccess) {//選取第一筆交易記錄

Sales_data trans=Sales_data(cin);//存放資料給下一筆交易記錄使用的變數

//while(read(cin, trans)) { //選取剩餘的交易記錄

while(trans.readSeccess) { //選取剩餘的交易記錄

if (total. isbn ()==trans.isbn())//檢查isbns

total.combine(trans);//更新累計總和

else {

print(cout, total) << endl;//印出結果

total=trans ;//處理下一本書

}

if(!read(cin, trans))trans.readSeccess=false;//還要再選取下一筆交易記錄,讓trans移位

}

print(cout,total) << endl;//印出最後一筆交易記錄

}

else {

cerr << "No data?!" << endl;//通知使用者

}

}



另一式:while要改成 do while才行,因為第2筆已讀取

#include "Sales_data.h"

#include <iostream>

using namespace std;

int main() {

Sales_data total=Sales_data(cin);//存放累計和的變數

//if (read(cin, total)) {//選取第一筆交易記錄

if (total.readSeccess) {//選取第一筆交易記錄

Sales_data trans=Sales_data(cin);//存放資料給下一筆交易記錄使用的變數

//while(read(cin, trans)) { //選取剩餘的交易記錄

do { //選取剩餘的交易記錄

if (total. isbn ()==trans.isbn())//檢查isbns

total.combine(trans);//更新累計總和

else {

print(cout, total) << endl;//印出結果

total=trans ;//處理下一本書

}

} while (read(cin, trans));

print(cout,total) << endl;//印出最後一筆交易記錄

}

else {

cerr << "No data?!" << endl;//通知使用者

}

}





Sales_data.cpp:

#include "Sales_data.h"

#include<string>

#include<iostream>

using namespace std;



Sales_data::Sales_data(istream& is) {

if (read(is, *this)) readSeccess = true;

}



Sales_data::Sales_data(const string& bNo,const double bSize,const double price, const unsigned sdQ) {

bookNo = bNo; soldQ = sdQ; revenue = price * sdQ; bookSize = bSize;

}



Sales_data& Sales_data::combine(const Sales_data& sales_data1, const Sales_data& sales_data2)

{

this->bookNo = sales_data1.bookNo;

this->bookSize = sales_data1.bookSize;

this->soldQ = sales_data1.soldQ + sales_data2.soldQ;

this->revenue = sales_data1.revenue + sales_data2.revenue;

return *this; // TODO: insert return statement here

}

Sales_data& Sales_data::combine(const Sales_data& sales_data)

{

if (bookNo == "") bookNo = sales_data.bookNo;//因為這是Sales_data類別的成員函式,所以可以直接調用該類別內的所有成員名稱,不必全名稱

bookSize = sales_data.bookSize;

soldQ += sales_data.soldQ;

revenue += sales_data.revenue;

return *this;// TODO: insert return statement here

}

string Sales_data::isbn()const

{

return bookNo;

}



double Sales_data::avg_price()const

{

if (soldQ>0)

{

return revenue / soldQ;

}

return 0.0;

}

ostream& print(ostream& os, const Sales_data& sales_data) {

os << sales_data.isbn() << '\t' << sales_data.soldQ << '\t'

<< sales_data.revenue << '\t' << sales_data.avg_price();

return os;

}



istream& read(istream& is, Sales_data& sales_data) {//要改變引數值,參數一定要是參考,將引數用傳址(參考)方式傳遞

//decltype(cin)& read(istream is ,Sales_data sales_data) {

is >> sales_data.bookNo >> sales_data.soldQ >> sales_data.revenue;

return is;

}



Sales_data add(const Sales_data& sales_data1, const Sales_data& sales_data2)

{

Sales_data sum = sales_data1;

sum.combine(sales_data2);

return sum;

}



Sales_data.h:

#pragma once

#ifndef SALES_DATA_H

#define SALES_DATA_H

#include<string>

using namespace std;//千萬不要忘了這個

struct Sales_data {

Sales_data() = default;//預設建構器(constructor)用這式會較Sales_data() {}多二個建構器,蓋=default由編譯器創建2個額外的合成的預設建構器(synthesized default constructors) 56:00

//Sales_data() {}//與Sales_data() = default;應是一樣的,然不能寫在最前面,會遮蔽後面的建構器 50:00

//Sales_data() :bookNo{"000-000-000" } {}

Sales_data(const string &bNo) :bookNo{bNo } {}

Sales_data(const string &bNo, const double bSize, const double rvn) :bookNo{ bNo }, bookSize{ bSize }, revenue{rvn} {}

Sales_data(const string &, const double bSize, const double, const unsigned);//在類別外定義的建構器

Sales_data(istream &);//在類別外定義的建構器

//Sales_data(istream& is){read(is, *this);}



bool readSeccess=false;//readSeccess記錄選取成功否

string bookNo;

double revenue{ 0.00 };//總營收-營業額

unsigned soldQ{ 0 };

double bookSize{0.00};

Sales_data& combine(const Sales_data&, const Sales_data&);//成員函式宣告一定要在類別內,定義可在此外

Sales_data& combine(const Sales_data&);//要改變this及其屬性值就不能再在參數列後加上const;因為加上const後this成了指向常值的常值指標,被指向的東西是不能被改變的了

string isbn()const;

double avg_price()const;

};

ostream& print(ostream& , const Sales_data&);

istream& read(istream& , Sales_data& );

Sales_data add(const Sales_data&, const Sales_data&);

#endif // !SALES_DATA_H



練習7.14

3:38:50

#include "Sales_data.h"

#include <iostream>

using namespace std;

int main() {

Sales_data sd;

print(cout, sd)<<endl;

}

Sales_data.h:

struct Sales_data {

Sales_data() {

readSeccess = false ; bookNo = "";

revenue = 0.00; soldQ = 0; bookSize = 0.00;

}

//Sales_data() = default;//預設建構器(constructor)用這式會較Sales_data() {}多二個建構器,蓋=default由編譯器創建2個額外的合成的預設建構器(synthesized default constructors)

3:50:30

練習7.15

Person.h

#ifndef PERSON_H

#define PERSON_H

#include<string>

#include<iostream>

using namespace std;

struct Person{

//Person()=default;

Person(){

name = "someone";

address = "somewhere";

}

Person(const string name, const string& address) :name(name),address(address){}

Person(istream&);

string name;

string address ;

string addressMethod()const;

string nameMethod()const;

};

istream& read(istream&,Person&);

ostream& print(ostream&,const Person&);

#endif

Person.cpp

#include "Person.h"



Person::Person(istream& is)

{

read(cin, *this);

}



string Person::addressMethod() const

{

return address;

}



string Person::nameMethod() const

{

return name;

}

istream& read(istream& is,Person& p){

is>>p.name>>p.address;

return is;

}

ostream& print(ostream& os,const Person& p){

os<<p.nameMethod()<<'\t'<<p.addressMethod();

return os;

}



Run:

#include<vector>

#include "Person.h"

#include <iostream>

using namespace std;

int main() {

Person p;

Person p1 = Person("孫守真", "士林區");

Person p2 = Person(cin);

vector<Person>vecPerson{ p,p1,p2 };

for(Person p:vecPerson)

print(cout,p)<<endl;

}



3:52:50 未錄到的請看臉書直播 第165集

7.1.5. Copy, Assignment, and Destruction

留言

熱門文章