C++自修入門實境秀、C++ Primer 5版研讀秀 50/ ~ Part II The C++ Library v8 IO 程式庫 8.1....
練習7.57
第49集 8:7:59 第50集1:5:00
Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H
#include<string>
#include<vector>
//#include<iostream>
using namespace std;
class Account
{
public:
typedef string str;
Account(str Name,str telephoneNum,str Address,str Gender);
~Account();
void calculate() {amount+=amount*interestRate; }
static double rate() { return interestRate; }
//static void rate(double);
private:
str name;//owner
str no_="000-00-00";// account number
str tel;//telephone
str address;
str gender;
double amount=0.00;
vector<str>transactions;
static double interestRate;
static double initRate();//Account.cpp檔定義上還沒解決
};
double Account::interestRate = 0.00;
Account::Account(str Name,str telephoneNum,str Address,str Gender)
:name(Name),tel(telephoneNum),address(Address),gender(Gender)
{
initRate();
}
inline double Account::initRate()
{
return interestRate= 0.0;
}
Account::~Account()
{
}
#endif
run:
#include"Account.h"
#include <iostream>
using namespace std;
int main() {
Account a("孫守真", "0936188888", "臺北市士林區", "M");
cout << a.rate() << endl;;
}
1:7:20
頁305
Chapter Summary
本章總結
Classes are the most fundamental feature in C++. Classes let us define new types for our applications, making our programs shorter and easier to modify.
Data abstraction—the ability to define both data and function members—and encapsulation—the ability to protect class members from general access—are
fundamental to classes.
We encapsulate a class by defining its implementation members as private.
Classes may define constructors, which are special member functions that control how objects are initialized.
Constructors should use a constructor initializer list to initialize all the data members.
Classes may also define mutable or static members. A mutable member is a data member that is never const; its value may be changed inside a const member function. A static member can be either function or data; static members exist independently of the objects of the class type.
可見一個類別的成員只有二類:函式成員(成員函式)與資料成員。錯!三種:還有型別成員(type member)。參見下文 class 詞條處。
靜態成員的存在是獨立於類別型別的對象物件之外的
1:20:10
Defined Terms
已經學過的詞彙(術語、專有名詞)
abstract data type Data structure that encapsulates (hides) its implementation.
封裝就是讓人不知葫蘆裡賣什麼藥,所以叫抽象化
access specifier (存取指定符)
Specifiers may appear multiple times within a class.
可見存取指定符不必只出現一次
彙總類別(aggregate class):
aggregate class Class with only public data members that has no in-class initializers or constructors. Members of an aggregate can be initialized by a brace-enclosed list of initializers.
可見彙總類別是沒有初始化的,所以其成員才都是公開的,讓此種類別的使用者能夠用特殊的初始器串列(initializer list)來初始化它的資料成員值
1:28:20
class C++ mechanism for defining our own abstract data types. Classes may have data, function, or type members. A class defines a new type and a new scope.
1:33:00
class declaration The keyword class (or struct ) followed by the class name followed by a semicolon. If a class is declared but not defined, it is an incomplete type.
1:39:10
普通ordinary的成員就是不是 static也不是mutable:
常值成員函式:
const member function A member function that may not change an object’s ordinary (i.e., neither static nor mutable ) data members. The this pointer in a const member is a pointer to const . A member function may be overloaded based on whether the function is const .
建構器:
constructor A special member function used to initialize objects. Each constructor should give each data member a well-defined initial value.
轉換建構器,隱含轉型:
converting constructor A non explicit constructor that can be called with a single argument. Such constructors implicitly convert from the argument’s type to the class type.
頁306
資料抽象化:
1:47:00
data abstraction Programming technique that focuses on the interface to a type. Data abstraction lets programmers ignore the details of how a type is represented and think instead about the operations that the type can perform. Data abstraction is fundamental to both object-oriented and generic programming.
1:51:24
default constructor Constructor that is used if no initializer is supplied.
1:52:00
委派建構器:(推託建構器,把自己該做的事推給別人去做)
delegating constructor Constructor with a constructor-initializer list that has one entry that designates another constructor of the same class to do the initialization.
1:55:00
encapsulation Separation of implementation from interface; encapsulation hides the implementation details of a type. In C++, encapsulation is enforced by putting the implementation in the private part of a class.
明確的建構器:(正文好像都沒翻)
explicit constructor
⑧找對主詞 明確什麼?明確轉型也。
1:59:00
先行的宣告(先行宣告、前向宣告、前置宣告):
forward declaration Declaration of an as yet undefined name. Most often used to refer to the declaration of a class that appears prior to the definition of that class. See incomplete type.
2:3:20
implementation (實作):
implementation The (usually private) members of a class that define the data and any operations that are not intended for use by code that uses the type.
可見不要把「實作」看得很抽象,其實就是一個類別中不公開不對使用它的公開的部分,就叫實作。相對的,打算公開的就是介面。
介面vs實作
2:7:40
incomplete type (不完整的型別)
參考、指標、靜態成員都可以使用不完整的型別
2:10:30
interface The ( public ) operations supported by a type. Ordinarily, the interface does not include data members.
通常介面是不包括資料成員(data member)在內的
資料成員通常都是實作、封裝(不公開 private)的部分
2:14:00
成員函式,分為一般的和static靜態的二種:
member function Class member that is a function. Ordinary member functions are bound to an object of the class type through the implicit this pointer. static member functions are not bound to an object and have no this pointer. Member functions may be overloaded; when they are, the implicit this pointer participates in the function matching.
2:16:10
mutable data member (可變的資料成員)
mutable data member Data member that is never const, even when it is a member of a const object. A mutable member can be changed inside a const function.
2:18:00
名稱的尋索:
name lookup Process by which the use of a name is matched to its declaration.
name lookup (名稱查找)一個名稱的使用與其宣告配對的過程。
跟宣告相匹配的名稱比對過程
2:24:40
Data members and utility functions used by the class that are not part of the type’s interface are usually declared private .
private members (私有成員)在一個private 存取指定符後定義的成員,只有朋友或其他的類別成員可以取用。類別有用到但不是型別介面一部分的資料成員和工具函式通常都會被宣告為 private。
資料成員一般都是private不公開的
工具函式(utility functions)
Ordinarily, only the functions that define the interface to the class should be defined in the public sections.
2:30:00 struc 和class定義類別的差別僅在預設的存取級別。
2:31:30
編譯器湊合的建構器:
synthesized default constructor The default constructor created (synthesized) by the compiler for classes that do not explicitly define any constructors. This constructor initializes the data members from their in-class initializers, if present; otherwise it default initializes the data members.
synthesized default constructor (合成的預設建構器)編譯器為沒有名確定義任何建構器的 類別所創建(合成)的預設建構器。若有提供,這個建構器會從它們的類別內初始器初始化資料成員;否則就預設初始化資料成員。
→明確
若有提供,這個建構器會從它們的類別內初始器初始化資料成員→若有提供類別內初始器,則這個建構器會從它們這些類別內初始器來初始化資料成員
=default就是請編譯器無論如何也幫我們湊合出一個預設建構器(default constructor)
even if the class has other constructors.
即使該類別沒有其他的建構器也一樣。
沒有→已有
中文版翻錯或誤植的還真不少。
C++自修入門實境秀、C++ Primer Fith Edition研讀秀(第二篇)
頁307
Part II: The C++ Library
第二篇 C++程式庫
2:57:00
3:13:30
We can think of a string as a special kind of container that contains only characters.
string型別與字串字面值(string literal)不同之處
The string type supports many, but not all, of the container operations.
頁308
這裡所謂的演算法也僅只是類似一般的運算或操作而已
3:21:18
The algorithms are generic in two ways: They can be applied to different kinds of sequences, and those sequences may contain elements of most types.
循序容器(sequential container)
3:27:00
關聯式容器(associative container)
一個關聯式容器中的元素是透過鍵值(key)來存取的。
3:33:00
This part concludes with Chapter 12, which looks at language and library facilities for managing dynamic memory.
這個部分以第12章做結,那裡會介紹用於管理動態記憶體的語言和程式庫機能。
→那裡會介紹C++與其程式庫機能對於動態記憶體的管理。
本書的language多指C++
3:36:00
智慧指標(smart pointers)
3:41:10
在主控文件的子文件將臉書的直播的連結插入,改寫「Sub 開新視窗到臉書直播()」
Sub 開新視窗到臉書直播()
Dim heading As Paragraph, a, docName As String, s As Integer, docOpened As Boolean
s = InStr(ActiveDocument.Name, "_子文件")
docName = Mid(ActiveDocument.Name, 1, s - 1) '取得主控文件的檔名
If s Then
For Each a In Documents
If a.Name = docName Then '主控文件有開啟
docOpened = True
Exit For
End If
Next a
If Not docOpened Then Documents.Open ActiveDocument.Path & "\" & docName & ".docm"
With Documents(docName)
.Activate
If docOpened Then .Windows.Add
End With
Else
Windows.Add
End If
For Each heading In ActiveWindow.Document.Paragraphs
If heading.Style = "標題 4" And heading.Range = "臉書直播" & Chr(13) Then
heading.Next.Range.Select
Selection.Collapse wdCollapseStart
For Each a In heading.Next.Range.Characters
If a = Chr(9) Then
If a.Next.Hyperlinks.Count = 0 Then
a.Next.Select '開始選取
Selection.MoveEndUntil Chr(9)
If VBA.Left(系統處理.GetClipboard(), 43) = "https://www.facebook.com/oscarsun72/videos/" Then _
Selection.Hyperlinks.Add Selection.Range, 系統處理.GetClipboard
Exit Sub
End If
End If
Next a
Exit For
End If
Next
End Sub
3:56:50 沒錄到的就看臉書直播第206集吧
3:40:59
頁309
Chapter 8. The IO Library
IO程式庫
4:2:40
C++並不會直接處理input輸入和output輸出
4:8:00
4:10:00
Additional types allow in-memory IO to and from string s.
還有額外的型別允許讀寫 string 的記憶體內 IO (in-memory IO )。
允許在記憶體內讀寫(輸入、輸出)string型別(從string讀出Input from,從記憶體內輸出(Output to)string
14、17兩章會更深入探討IO程式庫的其他capabilities(額外的功能)
頁310
4:18:00
• istream (input stream) type, which provides input operations
• ostream (output stream) type, which provides output operations
• cin , an istream object that reads the standard input
• cout , an ostream object that writes to the standard output
• cerr , an ostream object, typically used for program error messages, that writes to the standard error
• The >> operator, which is used to read input from an istream object
• The << operator, which is used to write output to an ostream object
• The getline function (§ 3.2.2 , p. 87 ), which reads a line of input from a given istream into a given string
8.1. The IO Classes
8.1 IO類別
4:29:00
Applications also may have to read and write languages that require wide-character support.
應用程式也可能會需要讀寫需要寬字元(wide-character)支援的語言。
中文資訊處理便是如此。
三個標頭檔定義了不同需求的處理型別:
These types, which are listed in Table 8.1 , are defined in three separate headers: iostream defines the basic types used to read from and write to a stream, fstream defines the types used to read and write named files, and sstream defines the types used to read and write in-memory string s.
表8.1:IO程式庫的型別和標頭
頁311
4:42:00
對寬字元(如中文字)的處理:
To support languages that use wide characters, the library defines a set of types and objects that manipulate wchar_t data (§ 2.1.1 , p. 32 ).
寬字元與一般字元都定義在同一個標頭檔中
4:48:50
Relationships among the IO Types
理論上裝置的類別與字元的大小並不會影響我們要執行的IO操作
wchar_t型別
wide character type
4:53:00
程式庫是藉由繼承的方式來讓我們在對stream處理時可以忽略上述(裝置的、字元的)各種的差異
The library lets us ignore the differences among these different kinds of streams by using inheritance.
As with templates (§ 3.3 , p. 96 ), we can use classes related by inheritance without understanding the details of how inheritance works.
Briefly, inheritance lets us say that a particular class inherits from another class.
say宣稱、宣告
The types ifstream and istringstream inherit from istream . Thus, we can use objects of type ifstream or istringstream as if they were istream objects.
Note
Everything that we cover in the remainder of this section applies equally to plain streams, file streams, and string streams and to the char or wide-character stream versions.
總之,不管是什麼裝置、什麼字元大小,都適用、都相通
5:7:40
8.1.1. No Copy or Assign for IO Objects
As we saw in § 7.1.3 (p. 261), we cannot copy or assign objects of the IO types:
ofstream out1, out2;
out1 = out2; // error: cannot assign stream objects
ofstream print(ofstream); // error: can't initialize the ofstream parameter
out2 = print(out2); // error: cannot copy stream objects
5:12:40
參數(藉由值傳遞引數頁209)與傳回值都是用拷貝的方式來傳遞的,所以:
Because we can’t copy the IO types, we cannot have a parameter or return type that is one of the stream types (§ 6.2.1 , p. 209 ).
只能透過參考來傳遞IO型別的資料流(stream)物件:
Functions that do IO typically pass and return the stream through references.
因為讀、寫資料流都會改變其原狀,所以對之的參考亦不能是對常值的參考(這樣的參考是不能改變其所參考之物件的,並不是它參考的東西是常值而不能去變動的)
頁312
8.1.2. Condition States
5:19:17
5:37:10
只有在沒有錯誤發生時,IO的操作才會持續
5:38:40
The easiest way to determine the state of a stream object is to use that object as a condition:
把資料流stream物件當作一個條件來用
Interrogating the State of a Stream
質詢一個資料流的狀態
檢查資料流現行的狀態
5:46:00
把一個資料流物件當作條件式來用只能知道它現行的狀態是有效否:
Using a stream as a condition tells us only whether the stream is valid.
5:49:00不同的錯誤狀態有不同的處理(應變)
The IO library defines a machine-dependent integral type named iostate that it uses to convey information about the state of a stream.
IO資料庫定義了一個獨立於機器的整數型別,名為iostate,
獨立於→依存於
This type is used as a collection of bits, in the same way that we used the quiz1 variable in § 4.8 (p. 154 ).
6:5:00
The IO classes define four constexpr values (§ 2.4.4 , p. 65 ) of type iostate that represent particular bit patterns位元模式. These values are used to indicate particular kinds of IO conditions. They can be used with the bitwise operators (§ 4.8 , p. 152 ) to test or set multiple flags in one operation.
在這裡,中文版又是根據pdf版來翻譯的:
到達檔案結尾時, eofbit與failbit兩者都會設定。
Reaching end-of-file sets both eofbit and failbit.
Google Play 圖書版:
Reaching end-of-file sets eofbit . If end-of-file does not follow valid input, failbit is also set. 6:14:30
可見這個是修訂版,而中文版竟然沒採用?
這些某某bit都是「flags」(翻成「標識」「標幟」,較「旗標」更貼切中文語境)不是有「旗幟」一詞嗎?怎麼不知道靈活用呢?中文程度真有差了吧!
The library also defines a set of functions to interrogate the state of these flags.(頁313)
Interrogate這裡翻成「檢查」或「取得」。「flags」翻成「標幟」6:22:00
用條件式來判斷:
If any of badbit , failbit , or eofbit are set, then a condition that evaluates that stream will fail.
頁313
By implication也就是說, the right way to determine the overall state of a stream is to use either good or fail .
Indeed, the code that is executed when we use a stream as a condition is equivalent to calling !fail() . The eof and bad operations reveal only whether those specific errors have occurred.
因為fail可以知道bad,而bad不能知道fail
這裡竟然承接前面未修訂版文字而來,因為failbit未必在eofbit觸發時被設定;除非eofbit觸發前讀取失敗,若讀取成功,則只會觸發eofbit而不會觸發failbit的設定(turn on)。可見光用fail來判斷是不夠的(當然對於錯誤是夠,會若要判斷讀完了沒、能不能再讀取下去,則就不行了)。
!fail() .→!(fail()&&eof()) .
表8.2 : IO程式庫條件狀態
表8.2 : IO程式庫條件狀態
strm::iostate strm是列於表8.1中的IO型別之一。iostate是一個獨立於機器 的整數型別,代表一個資料流的條件狀態。孫守真按:是依存於,示是獨立於
strm::badbit 用來表示一個資料流已毀損的strm::iostate值。表示完了,沒得搞了。
strm::failbit 用來表示一個IO運算失敗的strm::iostate值。還能有修復,再來的希望。6:10:00
strm::eofbit 用來表示一個資料流碰到檔案結尾的strm::iostate值。
strm::goodbit 用來表示一個資料流並未處在錯誤狀態的strm::iostate值。這個 值保證是零。
s.eof() 如果資料流s中的eofbit有設定,就為true。
s.fail() 如果資料流s中的failbit或badbit有設定,就為true。
s.bad() 如果資料流s中的badbit有設定,就為true。
s.good() 如果資料流s處於有效狀態,就為true。
s.clear() 將資料流s中所有的條件值都重置為有效狀態。回傳void。
s.clear(flags) 將s的條件重置為flags。flags的型別為strm::iostate。回傳 void。
s.setstate(flags) 將所指定的條件新增到s。flags的型別為strm::iostate。回傳 void。
s.rdstate() 將s目前的條件回傳作為一個sfrm::iostate值。
Managing the Condition State
6:36:40
The rdstate member returns an iostate value that corresponds to the current state of the stream. The
rd應該是read的意思
6:50:20
頁314
The version of clear that takes an argument expects an iostate value that represents the new state of the stream. To turn off a single condition, we use the rdstate member and the bitwise operators to produce the desired new state.
For example, the following turns off failbit and badbit but leaves eofbit untouched:
// turns off failbit and badbit but all other bits unchanged
cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
練習8.1
6:58:40
7:44:30與下一題兩題一起解決
練習8.2
#include <iostream>
#include<vector>
using namespace std;
istream& func(istream& is) {
int i; vector<int>veci;
while (!is.eof())
{
is >> i;
if (!is.eof())
veci.push_back(i);
}
for (int a : veci)
{
cout << a;
cout << endl;
} cin.clear();
//cin.setstate();
return cin;
}
int main() {
istream& i = func(cin);
cout << i.rdstate() << endl;
}
練習8.3
#include <iostream>
#include<vector>
using namespace std;
istream& func(istream& is) {
int i; vector<int>veci;
while (!is.fail()&&!is.eof()&&!is.bad())
{
is >> i;
if (!is.fail() &&!is.eof() && !is.bad())
veci.push_back(i);
}
for (int a : veci)
{
cout << a;
cout << endl;
} cin.clear();
//cin.setstate();
return cin;
}
int main() {
istream& i = func(cin);
cout << i.rdstate() << endl;
}
7:57:00
8.1.3. Managing the Output Buffer
緩衝區是幹什麼用的?
Each output stream manages a buffer, which it uses to hold the data that the program reads and writes.
when the following code is executed
os << "please enter a value: ";
the literal string might be printed immediately, or the operating system might store the data in a buffer to be printed later. Using a buffer allows the operating system to combine several output operations from our program into a single system-level write. Because writing to a device can be time-consuming, letting the operating system combine several output operations into a single write can provide an important performance boost.
緩衝區的flush(排清)就是將其資料寫入到輸出的裝置或檔案中
8:7:00
操作符(manipulator):endl、unitbuf
頁315
Flushing the Output Buffer
8:13:00
endl的意義:
Our programs have already used the endl manipulator, which ends the current line and flushes the buffer. There are two other similar manipulators: flush and ends.
flush flushes the stream but adds no characters to the output;
ends inserts a null character into the buffer and then flushes it:
cout << "hi!" << endl; // writes hi and a newline, then flushes the buffer
cout << "hi!" << flush; // writes hi, then flushes the buffer; adds no data
cout << "hi!" << ends; // writes hi and a null, then flushes the buffer
所以操作符(manipulator)有:endl、flush、ends、unitbuf、nounitbuf
The unitbuf Manipulator
8:22:00
③字形結構兼音義 ③字形結構換部首
nounitbuf
cout << unitbuf; // all writes will be flushed immediately
// any output is flushed immediately, no buffering
cout << nounitbuf; // returns to normal buffering
8:27:00
Caution:Buffers Are Not Flushed If the Program Crashes
注意:如果程式當掉,緩衝區不會排清
只要有crash就沒有flush
When you debug a program that has crashed, it is essential to make sure that any output you think should have been written was actually flushed. Countless hours of programmer time have been wasted tracking through code that appeared not to have executed when in fact the buffer had not been flushed and the output was pending when the program crashed.
除錯一個當掉的程式時,一定要確保你認為應該被寫出的任何輸出都有實際被排清。程式設計師花了很多時間在追查看似沒有執行但實際上是緩衝區沒有排清,因而程式當掉時輸出未實行的程式碼。
→程式設計師花了很多時間在追查看似沒有執行的程式碼,但實際上是緩衝區沒有排清,而在程式當掉的時候,輸出因而被擱置的程式碼。
要確保在程式當掉後,有排清(flush)緩衝區中尚未印出的任何資料
Tying Input and Output Streams Together
9:3:00
綁定是為了排清ostream,讓在使用instrem時,不會有殘餘osteam資料在緩衝區。
Note :Interactive systems usually should tie their input stream to their output stream. Doing so means that all output, which might include prompts to the user, will be written before attempting to read the input.
8:57:40
頁316
We can tie either an istream or an ostream object to another ostream:
cin.tie(&cout); // illustration only: the library ties cin and cout for us
// old_tie points to the stream (if any) currently tied to cin
ostream *old_tie = cin.tie(nullptr); // cin is no longer tied
// ties cin and cerr; not a good idea because cin should be tied to cout
cin.tie(&cerr); // reading cin flushes cerr, not cout
cin.tie(old_tie); // reestablish normal tie between cin and cout
To tie a given stream to a new output stream, we pass tie a pointer to the new stream. To untie the stream completely, we pass a null pointer.
Each stream can be tied to at most one stream at a time. However, multiple streams can tie themselves to the same ostream.
留言