跳到主要內容

第三章 類別與物件簡介

C++  How to Program 7/E 筆記
第三章 類別與物件簡介
學習目標
  • 如何定義類別,並使用類別建立物件
  • 如何在類別中定義成員函式,以實作類別的行為
  • 如何在類別中宣告資料成員,以實作類別的屬性
  • 如何呼叫物件的成員函式執行其工作
  • 類別資料成員與函式區域變數的差異
  • 建立物件時,如何使用建構子確保物件資料的初始化
  • 如何建構類別,已將其介面與實作分開,提高再利用



螢幕快照 2016-05-18 下午6.59.17.png


名詞解釋.png


GradeBook 類別的UML類別示意圖

在UML中,妹個類別都會在UML類別示意圖(UML class diagram)中以一個長方形代表,裡面有三個部分。




中間空,的表示GradeBook 類別沒有任何屬性。
第三行「+」表示displayMessage是一種UML公用(public)型的操作。(即C++的public 成員函式)
()是用來建立操作模型。在此範例中displayMessage無需額外資料便可執行工作。


定義一個具有「參數」的成員函式

參數(parameter) 可提供成員函式在執行工作所需要的額外資訊。
就如同汽車需要加速,參數即是在幫助汽車決定加速程度。
呼叫函式時,呼叫者會提供每個參數的「值」——>即引數(Argument)


圖解
類比.png


詳解.png


此時的GradeBook 類別的UML 類別示意圖




資料成員、set 函式與 get函式



我們將程式的所有辨識都宣告在main函式中,在函式定義主體中宣告的變數,就稱為區域變數(local variable)。區域變數要先宣告,才能在函式中使用。而在這個該函數之外的地方皆無法存取這個變數。(當然有例外)


類別通常由一或多個成員函式組成,這些函式可操控特定物件的屬性。
屬性由類別定義中的變數表示,這種變數稱作資料成員(data member)。資料成員會在類別定義中宣告,但他的宣告在成員函式定義主體的外部


在下方範例中Gradebook類別將課程名稱當作資料成員,因此可在程式中隨時使用或修改它。


什麼是資料成員.jpg
原則上,資料成員應宣告為private,成員函式應宣告為public
雖然public 和private存取修飾子可以重複交錯,但最好統一羅列。
用存取修飾子private宣告資料成員稱作資料隱藏(data hiding)。當成是建立(實體化)一個 GradeBook 物件時,此物件就封裝(隱藏)了資料成員courseName,只有該類別的成員函式能存取他。


含一個資料成員、一個set 函式與get函式的GradeBook UML類別示意圖

courseName 屬性的UML型別是String,對應到 C++ 的 string。資料成員courseName 在C++中是 private,所以類別示意圖在屬性名稱前面加上減號 (-)。


  • setCourseName 操作有一個String型別的參數,叫做name。
  • getCourseName在C++中的傳回型別是String,因此在()之後以「:string」表示。
  • setCourseName、displayMessage不會傳回任何值(傳回void),故()後方為空。


以建構子將物件初始化



在前面的範例中,建立GradeBook 物件時,資料成員courseName 會預設初始化為空字串。若在建立時,想同時提供課程名稱呢?
⇒⇒所宣告的每個類別都可提供建構子(constructor)


*建構子是一種特殊的成員函式,名稱必須和類別相同,編譯器才能區別他與其他成員函式。建構子與其他成員函式的一個重要差異,就是建構子不能還回數值,因此他不能指定傳回型別(就連void也不行)。通常,建構子都宣告為public
C++建立每個物件都要呼叫建構子,以確保程式使用物件前,每個物件均已初始化。建立物件時,就隱含了建構子的呼叫
若類別沒有明確寫出建構子,編譯器就提供一個預設建構子(default constructor),也就是沒有參數的建構子


建構子 .png


*為類別提供預設建構子的兩種方式
沒有參數的建構子就叫預設建構子。預設建構子的建立方式有兩種:
  1. 若類別沒有定義建構子,編譯器就會自行為他建立一個預設建構子。為初始化的變數通常會包含一個「垃圾值」(garbage value)
  2. 由你明確定義一個沒有參數的建構子。這種預設建構子可執行你指定的初始化動作,若資料成員本身是類別物件,也會呼叫每個資料成員的預設建構子。


將建構子納入GradeBook 類別的UML類別示意圖


在此GradeBook 類別模型,他有一個建構子,其參數名稱是name,型別是string。
為了區分建構子和類別操作,UML在建構子名稱前面會加上
<<contructor>>。習慣上會將建構子放在其他操作前面。


✯✯✯ 將類別放在獨立檔案以提高重複使用性



建立類別定義的好處在於,若套件設定得當,程式設計者便可重複使用我們的類別。但是若有其他程序員想要使用GradeBook類別,得注意到不能全部照抄,否則會因為有兩個main韓式,而讓程序錯誤。
在Microsoft Visual C++編譯會產生以下錯誤:


error C2084: fucntion ‘int main(void)’ already has a body


而在GNU C++編譯器會產生如下錯誤


redefinition of ‘int main()’


標頭檔
前面的程式皆為副檔名 (.cpp),此檔稱作原始碼檔案(source-code file)包含GradeBook 類別定義和一個main函式
在建構物件導向C++程式時,通常會將可再利用的原始碼定義在副檔名為(.h)的檔案中,這就是標頭檔(header file)。程式使用#include箝制處理指令已函入標頭檔,藉此運用可再利用的軟體元件。


如何找到標頭檔
GradeBook.cpp檔案中,第四行檔名是以雙引號 (“ ”)包覆而非(< >)。程式原始碼檔案與使用者自定標頭檔通常會放在相同目錄下,當前置處理器碰到雙引號的標頭檔名時,會再與# include指令出現的檔案相同目錄中尋找標頭檔。若遇到的是<>的標頭檔時,會假設該逼頭飾C++標準函式庫的一部份,而不會尋找被前置處理的程式所在目錄。


將介面與實作分開
軟體工程基本守則——將介面與實作分開(separating interface from implementation)


類別介面(interface of a class)說明類別提供了「什麼」服務給用戶端以及如何要求這些服務,但沒有說明「如何」實作這些服務。類別介面由類別的public 成員函式組成

注意,每個函式標頭的成員函式名稱前面堆有類別名稱和::,這叫做二元使用域解析運算子(binary scope resolution operator)。他們會把每個成員函式綁到宣告成員函式與資料成員的GradeBook 類別定義上面
若不在函式前面加上「GradeBook :: 」,則編譯器就不知道這些函式是GradeBook 類別的成員函式,會把他們當成全域函式。(page3-31)






在程式裡,我們習慣將類別定義與使用該類別的用戶端程式碼分開,而為了不要讓類別定義中的成員函式實作被修改,進而影響到用戶端程式碼的失靈,因此在編寫程式時,會將類別定義在被分割成成:類別介面和類別實作。此時類別實作會被隱藏起來僅留下類別介面。

圖解
mmm
// GradeBook.cpp
// GradeBook member-fuction definitions.This file contains
// implementations of the member functions prototyped in GradeBook.h
#include <iostream>
#include "GradeBook.h" // include definition of class GradeBook
using namespace std;
// constructor initializes courseName with string supplied as argument
GradeBook::GradeBook (string name)
{
setCourseName( name ); // call set function to initialize courseName
} // end GradeBook constructor
// function to set the course name
void GradeBook::setCourseName( string name )
{
courseName = name; //store the course name in the object
} // end function setCourseName
//function to get the course naeme
string GradeBook::getCourseName()
{
return courseName; // return object's courseName
} // end function getCourseName
//display a welcome message to the GradeBook user
void GradeBook::displayMessage()
{
//call getCourseName to get the courseName
cout << "Welcome to the grade book for\n" << getCourseName()
<< "!" << endl;
} // end function displayMessage
view raw GradeBook.cpp hosted with ❤ by GitHub
// GradeBook.h
// GradeBook class definition. This file presents GradeBook's public
// interface without revealing the implementations of GradeBook's member
// functions, which are defined in GradeBook.cpp
#include <string > // class GradeBook uses C++ standard string class
using namespace std;
//GradeBook class definition
class Gradebook
{
public:
GradeBook (string ); // constructor that initializes courseName
void setCourseName ( string ); // function that sets the course name
string getCourseName(); // function that get the course name
void displayMessage(); // fuction that displays a welcome message
private:
string couseName; // course name for this GradeBook
};// end class GradeBook
view raw GradeBook.h hosted with ❤ by GitHub
// user.cpp
// GradeBook class demonstration after separating
//its interface from its implementation.
#include <iostream>
#include "GradeBook.h" // include definition of class GradeBook
using namespace std;
//fucntion main begins program execution
int main()
{
//create two GradeBook objects
GradeBook gradeBook1( "CS101 Introduction to C++ Programming");
GradeBook gradeBook2( "CS102 Data Strutures in C++");
//display initial value of courseName for each GradeBook
cout << "gradeBook1 created for course: " << gradeBook1.getCourseName()
<< " \ngradeBook2 created for course: " << grdeBook2.getCourseName()
<< endl;
} //end main
view raw user.cpp hosted with ❤ by GitHub

jjj
附錄:語法


GradeBook with “Welcome to the Grade Book!”
//
//Define class Gradebook with a member function displayMessage.
// create a GradeBook object, and call its displayMessage function.
#inclued <iostream>
using namespace std;

// GradeBook calss definition
class GradeBook
{
   public:
   //function that displays a welcome message to the GradeBook user
   void displayMessage()
   {
       cout << " Welcome to the Grade Book!" << endl;
   } //end function displayMessage
};// end class Gradebook

//function main begins program execution
int main()
{
   GradeBook myGradeBook; // create a GradeBook object named myGradeBook
   myGradeBook.displayMessage(); // call objet's displayMessage function
}


GradeBook add “couseName”
//
// Define class GradeBook with a member function that takes a parameter;
// Create a GradeBook object and call its displayMessage function.
# include <iostream>
# include <string> // program uses C++ standard string class
using namespace std;

// GradeBook calss definition
class GradeBook
{
   public:
   // function that displays a welcome message to the GradeBook user
   void displayMessage (string courseName)
   {
       cout << "Welcome to the grade book for\n" << courseName << "!"
       << endl;
   } // end function displayMessage
}; // end class GradeBook

//function main begins program execution
int main()
{
   string nameOfCourse; // string of characters to store the course name
   GradeBook myGradeBook; // create a GradeBook object named myGradeBook
   
   // prompt for and input course name
   cout << "Please enter the course name:" << endl;
   getline( cin, nameOfCourse ); // read a course name with blanks
   cout << endl; // out put a blank line
   
   // call myGradeBook's displayMessage function
   // and pass nameOfCourse as an argument
   myGradeBook.displayMessage( nameOfCourse );
} // end main


資料成員、set、get
//
// define class GradeBook that contains a courseName data member
// and member functions to set and get its value;
// Create and manipulate a GradeBook object with these functions.
# include <iostream>
# include <string>
using namespace std;

//GradeBook class definition
class GradeBook
{
   public:
   // function that sets the course name
   void setCourseName (string name)
   {
       courseName =name;//store the course name in the project
   } // end function setCourseName
   
   // function that gets the course name
   string getCourseName()
   {
       return courseName; // return the object's courseName
   }// end function getCourseName
   
   // fucntion that displays a welcome message
   void displayMessage()
   {
       // this statement callls getCourseName to get the
       // name of the course this GradeBook represents
       cout << "Welcome to the grade book for \n" << getCourseName() << "!"
       << endl;
   }// end function displayMessage
   private:
   string courseName; // course name for this GradeBook
}; // end class GradeBook

// function main begins program execution
int main()
{
   string nameOfCourse; // string of characters to store the course name
   GradeBook myGradeBook; // create a GradeBook object named myGradeBook
   
   //display initial value of courseName
   cout << "Initial course name is:" << myGradeBook.getCourseName()
   << endl;
   
   //prompt for, input and set course name
   cout << "\n Please enter the course name:" << endl;
   getline(cin, nameOfCourse); // read a course name with blanks
   myGradeBook.setCourseName(nameOfCourse); // set the couse name
   
   cout << endl;// outputs a blank line
   myGradeBook.displayMessage();// display message with new course name
}//end main


定義建構子
//
// Instantiating multiple objects of the GradeBook class and using
// the GradBook constructor to specify the course name
// when each GradeBook object is created.
#include <iostream>
#include <string> //program uses C++ standard string class
using namespace std;

// GradeBook class definition
class GradeBook
{
   public:
   // constructor initializes courseName with string supplied as argument
   GradeBook ( string name )
   {
       setCourseName( name ); //call set function to initialize courseName
   }// end GradeBook constructor
   
   //function to st the course name
   void setCourseName( string name )
   {
       courseName = name; // stroe the coure name in the object
   } // end function setCourseName
   
   //fucntion to get the coursename
   string getCourseName()
   {
       return courseName; // return object's courseName
   } //end fucntion getCourseName
   
   //display a welcomemessage to the GradeBook user
   void displayMessage()
   {
       //call getCourseName to get the courseName
       cout << "Welcome to the grade book for\n" << getCourseName()
       << "!" << endl;
   } //end function displayMessage
   private:
   string courseName; // course name for this GradeBook
}; //end class GradeBook

//function main begins program execution
int main()
{
   //create two GradeBook objects
   GradeBook gradeBook1("CS101 introduction to C++ Programming");
   GradeBook gradeBook2("CS102 Data Structures in C++");
   
   //display initial value of courseName for each GradeBook
   cout << "gradeBook1 created for course:" << gradeBook1.getCourseName()
       << "\ngradeBook2 created for course:" << gradeBook2.getCourseName()
       << endl;
} // end main


資料參考:
http://pydoing.blogspot.tw/2012/10/cpp-interface-and-implementation.html

留言

這個網誌中的熱門文章

【Quora 翻譯&整理】對於程式初學者嘗試解決問題的好網站推薦

原文出處: What are some suggested websites to solve programming problems for beginners? (2016/5/15) 此篇文章強調的是去參加project的那種網站推薦

第一章 電腦、網際網路與全球資訊網簡介

C++  How to Program 7/E 筆記 第一章 電腦、網際網路與全球資訊網簡介 學習目標 基本軟硬體觀念 物件技術觀念(類別、物件、屬性、行為、封裝、繼承) 程式語言的種類 典型的C++開發環境 業界標準物件導向素模語言——UML 沿革 網際網路、球球資訊網與Web 2.0現象的沿革 在Linux 的GNU C++ 與在Microsoft Visual C++環境中測試C++ 應用程式 *結構化程式設計(structured programming) *物件導向程式設計

【 Intro to Java Programming 】Lesson 1 : Introduction-5 (Algorithms)

This Notes is according to the udacity free course : Intro to Java Programming Lesson 1 : Introduction-5(Algorithms) Key Word : pseudocode Algorithms just like a doing things protocol+condition. Without protocol+condition, you can not make choice or do the decision. So if you want to buy car, you know the car speed and you don't consider the car price or the car condition, so it is your thought, it is the algorithm you buy a car. For computer, we give them the program ===>for them to do algorithm, but now we try to write done in Pseudocode. Pseudocode write in "spoken language" which help us to understand the problem so we can translate them into computer language ==>JAVA Code.org maybe it could help you have fun from learning code