奇怪的C初始化行为
我有两个类Base和Derived from it:
class Base{ public: Base(int = 0); Base(Base&); Base& operator=(const Base&); protected: int protectedData; private: int baseData; }; /////////////DERIVED CLASS class Derived: public Base{ public: Derived(int = 0); Derived(Derived&); Derived(Base&); Derived& operator=(const Derived&); private: int derivedData; }; 执行功能 ///////////BASE FUNCTIONS Base::Base(int value): protectedData(value),baseData(value) { cout << "base C'tor" << endl; } Base::Base(Base& base) { baseData = base.baseData; protectedData = base.protectedData; cout << "base Copy C'tor" << endl; } Base& Base::operator=(const Base& base) { if(this == &base) return *this; baseData = base.baseData; protectedData = base.protectedData; cout << "Base::operator=" << endl; return *this; } ///////////DERIVED FUNCTIONS Derived::Derived(int value): Base(value),derivedData(value) { cout << "derived C'tor" << endl; } Derived::Derived(Derived& derived) : Base(derived) { derivedData = derived.derivedData; cout << "derived Copy C'tor" << endl; } Derived::Derived(Base& base) : Base(base),derivedData(0) { cout << " Derived(Base&) is called " << endl; } Derived& Derived::operator=(const Derived& derived) { if(this == &derived) return *this; derivedData = derived.derivedData; cout << "Derived::operator=" << endl; return *this; } 以下是我的主要内容: Base base(1); Derived derived1 = base; 编译器给我一个错误: ..main.cpp:16: error: no matching function for call to `Derived::Derived(Derived)' ..base.h:34: note: candidates are: Derived::Derived(Base&) ..base.h:33: note: Derived::Derived(Derived&) ..base.h:32: note: Derived::Derived(int) ..main.cpp:16: error: initializing temporary from result of `Derived::Derived(Base&)' 但是当我在主要的时候: Base base(1); Derived derived1(base); 它完美地运作.为什么? EDITED 好的,谢谢大家,我用const检查了一切,并且一切正常,但是我也检查了所有的电话,在这两种情况下我收到: base C'tor base Copy C'tor Derived(Base&) 我的问题是,为什么?你说我实际上打电话给: base C'tor base Copy C'tor Derived(Base&) Derived copy c'tor //<-note,why this one is missing? 解决方法
改变这些构造函数
Base(Base&); Derived(Derived&); Derived(Base&); 要获取const引用: Base(const Base&); Derived(const Derived&); Derived(const Base&); 前者不能接受临时值,后者可以.编译器想要转换 Derived derived1 = base; 成 Derived derived1(Derived(base)); 但它不能,因为Derived(base)是一个临时值,并且没有可以获取临时Derived实例的Derived构造函数. 编辑: 请注意,由于copy elision,有时很难通过在构造函数中放入一堆cout调用来查看编译器实际执行的操作. Copy elision允许编译器在某些情况下消除副本,即使这些副本有副作用(如打印输出).在Wikipedia中有一个相当好的讨论.如果你使用g,你可以添加–no-elide-constructors开关,你会看到所有预期的副本发生. 另外,this answer by litb到另一个相关问题有很多关于直接初始化和复制初始化之间细微差别的详细讨论.这是很好的阅读! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |