#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