作者godfat (godfat 真常)
看板C_and_CPP
标题Re: [问题] c++ 的物件使用一问
时间Thu Feb 9 04:24:35 2006
......先行声明,以下内容大多出自於猜测
如有错误希望大家可以出声指正,以免造成误导与混淆 :(
: ========================
: 你的问题其实只有一个关键:
: ic::ic(src& s)
: 接受的是 non-const reference
: 你传暂时物件进去,那就等於传 const 物件了,这样当然会错罗
: 否则你可以试试把 ic(src& s) 参数改成 const src &s 看看
: 就可以运作了
: 函式的 reference 参数
: 如果没加 const,就表示接收进来的物件可能被修改
: 所以如果有传入暂时物件的可能,一定要加 const
: ==========
我觉得不太像是这个问题,我写几个测试 code
根据原 po 的问题改编,g++ 3.4.2 得错误讯息
error: no matching function for call to
`DerivedA::DerivedA(Derived A(&)(DerivedB))'
note: candidates are: DerivedA::DerivedA(const DerivedA&)
note: DerivedA::DerivedA(const Base&)
struct Base{Base(){}};
struct DerivedA: public Base{
DerivedA(const Base&){}
DerivedA(const DerivedA&){}
};
struct DerivedB: public Base{
DerivedB(){}
DerivedB(const Base&){}
};
int main(){
DerivedA a(Base());
DerivedA b(DerivedB(a));
DerivedA c(b); // at this line
}
b 是一个普通的 DerivedA 物件,可是 const DerivedA& 和 const Base& 都不吃
根据错误讯息,b 的型别是 Derived A(&)(DerivedB)
再来看 Comeau C++ 4.3.3 的错误讯息:
(from:
http://www.comeaucomputing.com/tryitout/)
(btw, 我好想买喔)
error: no instance of constructor "DerivedA::DerivedA"
matches the argument list
The argument types that you used are: (DerivedA (DerivedB))
DerivedA c(b);
^
也就是说,他认为 b 的型别是 DerivedA (DerivedB) 了
把上述 code 做一点修正:
把 struct DerivedA 移到 DerivedB 下面
在 DerivedA 里追加一个 c'tor 叫
DerivedA(const DerivedA(DerivedB)){}
(模仿 Comeau 的型别)
在 g++ 下,再得错误讯息:(我只列改变)
note: candidates are:
DerivedA::DerivedA(const DerivedA(*)(DerivedB)) <near match>
...
看到 g++ 的提示,near match...(差一个 const)
而 Comeau 的 compile 结果呢?
很抱歉,还是 error, 不过给的错误讯息没有任何改变
(这点就觉得 g++ 错误讯息比较方便了…
有时候看不懂的型别就 compile 没差,反正会告诉你)
再改一次,这次加个 &
DerivedA(const DerivedA& (DerivedB)){}
错误讯息:
note: candidates are:
DerivedA::DerivedA(const DerivedA&(*)(DerivedB)) <near match>
...
这次改成 g++ 的提示:
DerivedA(const DerivedA(&)(DerivedB)){}
这样…还是不能通过编译
note: candidates are:
DerivedA::DerivedA(const DerivedA(&)(DerivedB))
...
这次连 <near match> 都没给了
把 const 拿掉,变成:
DerivedA(DerivedA(&)(DerivedB)){}
这下终於顺利通过 compile 了,g++ 和 comeau 都一样
而如果改成这样:
DerivedA(DerivedA(DerivedB)){}
其实也可以通过编译,同样 g++ 和 comeau 都一样
这样也可以:
DerivedA(DerivedA(*)(DerivedB)){}
ok, 回头去看其中一个型别:
typeA(*)(typeB)
不觉得很像 function pointer 吗?
那麽 typeA(&)(typeB) 又是什麽?
答案是实体 function...(我居然测试测半天才发现这个事实)
请再回到最早的 code, 并在最下面加上这个:
Base base;
b(base);
b(Base());
得 g++ 错误讯息
undefined reference to `b(DerivedB)'
undefined reference to `b(DerivedB)'
comeau c++... online 版没有 link, 所以没有错误 :Q
ok, 说得乱七八糟,讲个结论吧
...嗯,刚刚本来想举些例子做结论
不过举了几个例子之後又发现一些奇妙的东西
比方说
int value = 5;
TypeA a(TypeB(value));
或
const int value = 5;
TypeA a(TypeB(value));
则 a 是一个 function
TypeA a(TypeB(5));
则 a 是一个 TypeA 物件,用 TypeB::TypeB(int) 建立的暂时物件建立的物件
我被这搞糊涂了...
不过看来假使我这样写:
int(int)
则这代表型别:
int(*)(int)
或
int(&)(int)
我想这也是为什麽 boost::function<int(int)> 可以这样用了
另外 g++ 有时候也会将 int(int) 视为 int(&)(int)
我想这可能是最佳化机制的缘故…(纯猜测)
(昏倒, C++ 好谜... 避免使用这种吊诡的用法吧)
(毕竟平时应该不会用暂时物件来建立物件吧)
(再钻研下去似乎过於没意义了)
--
By Gamers, For Gamers - from the past Interplay
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.132.128.238
※ 编辑: godfat 来自: 220.132.128.238 (02/09 04:27)