終於進入第二章了!
第一章是C++的一些基本概念,而第二章是關於 "Constructors, Destructors, and Assignment Operators" ,也是C++物件的不可或缺的角色─管理物件的生成、初始化、清理與賦值,也因為他們無所不在,更要注意它們的運用,以免造成的傷害也是影響廣大!
首先登場的就是:
Know that functions C++ silently writes and calls
當寫出一個class的時候,C++其實會默默幫你補充以下幾項:
而仰賴C++自動生成的這幾項,都會是 "public" 且 "inline" 的。
如同以下範例,當你寫了這樣...
class Empty();
其實效果就等同:
class Empty{
public:
Empty() {...} // default constructor
Empty(const Empty& rhs) {...} // copy constructor
~Empty() {...} // destructor
Empty& operator=(const Empty &rhs) {...} // copy assignment operator
}
當用到這些function的時候他們就會被產生,那什麼時候會用到他們呢?
Empty e1; // default constructor; destructor
Empty e2(e1); // copy constructor
e2 = e1; // cp[y assigment operator operator
Constructor跟 destructor不必多說,就是把其中base class跟non-static data members的自動初始化跟destruct做一做。其中可以注意一下,如果有自行宣告constructor,那default constructor就不會被產生!不用擔心自己定義好需要有參數的constructor之後,還可以不用參數直接產生對應物件(例如:
templage<typeName T>
class NamedObject{
public:
NamedObject(const std::string& name, const T& value);
private:
std::string nameValue;
T objectValue;
那以下是行不通的!
NamedObject n1; // error!
)
另外,自動生成的destructor會是non-virtual的,除非!這個class是繼承自一個有把destructor宣告為virtual的base class。
而copy constructor跟copy assignment operator則會複製source object的non-static data members到target object。例如上面這個物件
NamedObject<int> no1("Smallest Prime Number", 2);
NamedObject<int> no2(no1);
copy constructor會怎麼運作呢?首先nameValue
因為是string
,他有copy constructor,所以nameValue
的部分就照string的copy constructor把no1的string copy過去;而後面的objectValue
是int,他是built-in type,所以objectValue
則是會複製no1.objectValue的bits過去。copy assignment operator也是同樣運作方式。不過!以下情形例外:產生的assignment 不合法。這是什麼意思呢?假設NamedObject
變成這樣:
templage<typeName T>
class NamedObject{
public:
NamedObject(std::string& name, const T& value); // no const now!
private:
std::string& nameValue; // reference now!
const T objectValue; // const now!
而當我們這樣使用:
std::string newDog("A");
std::string oldDog("B");
NamedObject<int> a(newDog, 2);
NamedObject<int> b(oldDog, 20);
a=b;
此時,a
的nameValue
應該是什麼呢?它是reference,C++不允許reference參考到別的物件;退一步來說,就算可以改,這樣其他參考到同一位置的物件,也要跟著變嗎?另外objectValue
應該要變嗎?可是它是const...
而對於這種情形,C++就直接不給過。如果你的class裡面有reference member,你就需要自行定義copy assignment operator。除了reference type,const member也是比照辦理。
另外還有一種情形C++不會自動產生copy assignment operator─base class的copy assignment被宣告為private的derived class,因為C++自動產生的copy assignment operator需要可以handle base class的部分,但base class的copy assignment operator不給call,那就沒辦法了。
貼心重點提醒:
Compilers may implicitly generate a class's "default constructor", "copy constructor", "copy assigment operator", and "destructor."
這條準則其實就是提醒一下C++會自動產生這四大金剛,以及各個不會產生的情形就行了。如果之後有什麼情況想要避免,就要注意一下要把它ban掉(通常是不用)。
(皆取自參考資料)