作者khoguan (Khoguan Phuann)
看板C_and_CPP
标题Re: [问题] default constructor
时间Wed Jun 22 23:23:32 2005
※ 引述《WanCW (笨狐狸)》之铭言:
: ※ 引述《myselves (...)》之铭言:
: : 而copy constructor的型态未必要跟class本身一样
: : 例如 Xxxxx(const Yyyyy &rhs); 是可以的(通常都是Xxxxx(const Xxxxx &rhs);)
: : 当
: : Yyyyy y;
: : Xxxxx x = y; //这时候 Xxxxx(const Yyyyy &rhs)会被呼叫
: 只有型态完全相同的, 才会被视为 Copy Constructor.
Y y1;
X x1 = y1;
这种写法,在「语意」上,是以 y1 为引数,呼叫 X(const Y&)
以产生一个 X 的暂时物件,然後再以这个 X 的暂时物件做引数,
呼叫 X(const X&) 来建构 x1 这个 X 的物件。「语意」上是如此,
但在compiler实作上,C++ 标准容许其做最佳化,呼叫 X(const Y&)
时,就直接建构出 x1, 而不是执行 X(const Y&) 只产生过渡性的
暂时物件,接着再呼叫 X(const X&) 才终於建构出 x1。由於许多
编译器都有做这种最佳化,因此很容易让人误以为只需要有 X(const Y&)
就能写 X x1 = y1;
Anyway,编译器仍然得要求程式符合需要两层建构子的「语意」限制,
也就是说,即使是做这种最佳化的编译器,仍然得先检查 X(const X&)
这个建构子是不是能够被存取以执行,否则,就不能通过编译。例如:
class Y {};
class X {
public:
X() { cout << "X()\n"; }
X(const Y&) { cout << "X(const Y&)\n"; }
X(const X&) { cout << "X(const X&)\n"; }
};
int main()
{
Y y1;
X x1 = y1;
}
上述可以通过编译,并正确执行( <iostream>等等请自己加:)。但是
若动个手脚,将 X(const X&)移到 private: 区,那就不行通过编译啦。
class Y {};
class X {
public:
X() { cout << "X()\n"; }
X(const Y&) { cout << "X(const Y&)\n"; }
private:
X(const X&) { cout << "X(const X&)\n"; }
};
int main()
{
Y y1;
X x1 = y1;
}
Comeau compiler 的错误讯息说得很清楚:
error: "X::X(const X &)" is inaccessible
(Even though the copy was eliminated, the standard
still requires it to be accessible)
X x1 = y1;
^
这样就可看出 X(const X&) 对於 X x1 = y1; 这个叙述的必要性了。
当然,若根本不宣告 X(const X&) 的话,compiler 依标准会默默地
(implicitly)帮我们生出一个来,那当然还是可以编译执行的。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.130.208.168
1F:推 elsvent:要注意的是有用到pointer就要小心了 61.62.218.129 06/22
※ 编辑: khoguan 来自: 220.130.208.168 (06/23 11:53)