#include <iostream>
class P_Node {
friend class Picture;
protected:
P_Node() : use(1) {}
virtual ~P_Node() {}
private:
int use;
};
class Picture {
friend Picture frame(const Picture&);
public:
Picture() : p(new P_Node) {
std::cout << "Constructor\t" << "Picture::Picture()" << "\tcalled" << std::endl;
std::cout << "Picture p count\t" << p->use << std::endl;
}
Picture(const Picture& orig) : p(orig.p) {
std::cout << "Copy Constructor\t" << "Picture::Picture(const Picture&)" << "\tcalled" << std::endl;
std::cout << "Picture p count\t" << p->use << std::endl;
orig.p->use++;
}
~Picture() {
std::cout << "Destructor\t" << "Picture::~Picture()" << "\tcalled" << std::endl;
std::cout << "Picture p count before decrease\t" << p->use << std::endl;
if(--p->use == 0) {
std::cout << "Picture p count after decrease\t" << p->use << std::endl;
std::cout << "Deleted" << std::endl;
delete p;
}
}
Picture& operator=(const Picture& orig) {
std::cout << "operator=\t" << "Picture& Picture::operator=(const Picture& orig)" << "\tcalled" << std::endl;
std::cout << "Picture p count before decrease\t" << p->use << std::endl;
orig.p->use++;
if(--p->use == 0) {
std::cout << "Picture p count after decrease\t" << p->use << std::endl;
std::cout << "Deleted" << std::endl;
delete p;
}
p = orig.p;
return *this;
}
private:
Picture(P_Node* p_node) : p(p_node) {
std::cout << "Picture::Picture(P_Node* p_node)\tcalled" << std::endl;
}
P_Node *p;
};
class Frame_Pic : public P_Node {
friend Picture frame(const Picture&);
private:
Frame_Pic(const Picture& pic) : p(pic) {
std::cout << "Frame_Pic::Frame_Pic(const Picture& orig)" << "\tcalled" << std::endl;
}
Picture p;
};
Picture frame(const Picture& pic) {
return new Frame_Pic(pic);
}
int main() {
Picture my_pic;
Picture temp = frame(my_pic);
return 0;
}
結果是:
Constructor Picture::Picture() called Picture p count 1 Copy Constructor Picture::Picture(const Picture&) called Picture p count 1 Frame_Pic::Frame_Pic(const Picture& orig) called Picture::Picture(P_Node* p_node) called Destructor Picture::~Picture() called Picture p count before decrease 1 Picture p count after decrease 0 Deleted Destructor Picture::~Picture() called Picture p count before decrease 2 Destructor Picture::~Picture() called Picture p count before decrease 1 Picture p count after decrease 0 Deleted
我以前問一個關於這個代碼的內存管理問題,但這些答案的理解後,我仍然有一個問題析構函數和複製構造函數。據我瞭解,Picture temp = frame(my_pic)
將調用複製構造函數。
問題來了:
- 後爲什麼
Picture temp = frame(my_pic)
- 不叫拷貝構造函數,爲什麼被稱爲析構函數?
- 在
Picture frame(const Picture& pic)
,如果函數被調用,會調用複製構造函數嗎?我相信是這樣,因爲它會以價值回報'圖片'。 - 如果我將
Picture frame(const Picture& pic)
更改爲Picture frame(Picture p)
,函數調用時複製構造函數會調用兩次嗎? - 何時會調用複製構造函數?當這個類被函數按值返回時會發生嗎?當然後類通過值傳遞給一個函數?
- 什麼時候可以調用析構函數?每次變量的生命週期結束了嗎?這是否意味着如果我通過值將一個變量傳遞給一個函數,它的析構函數將在函數執行後被調用?
我現在搞砸了複製構造函數和析構函數,特別是當我有一個帶有返回值的函數和一些參數都通過值傳遞。
此外,任何人都可以幫我寫每條輸出字符串的評論嗎?這將是非常有益的。
注意,調用拷貝構造函數和賦值操作符可以自由編譯器的優化被淘汰,即使他們有副作用。這是編譯器被允許違反as-if規則的唯一兩個。 (當然,編譯器仍然需要不違反邏輯並將調用與ctors和dtors相匹配。) – sbi 2011-12-31 09:23:39
@outis:否。返回表達式的類型爲'Frame_Pic *'。'Frame_Pic'派生自'P_Node','P_Node *'通過私有構造函數隱式轉換爲'Picture',這很好,因爲'frame'被聲明爲朋友。正如函數聲明的那樣,主體返回一個'Picture'。 – 2011-12-31 09:27:06
@CharlesBailey所以代碼本身並不是_wrong_,但我絕對不會稱之爲好的做法。 – bames53 2011-12-31 10:07:49