谁能告诉我返回类型协变在以下代码中是如何工作的?classX{public:intx;};classY:publicOtherClass,publicX{};staticYinst;classA{public:virtualX*out()=0;};classB:publicA{public:virtualY*out(){return&inst;}};voidmain(){Bb;A*a=&b;//xandyhavedifferentaddresses.howandwhenisthisconversiondone??Y*y=b.out();X*x=a->out();}编辑:对不起,我一定不
我刚刚试过这段代码:structFaceOfPast{virtualvoidSmile()=0;};structFaceOfFuture{virtualvoidSmile()=0;};structJanus:publicFaceOfPast,publicFaceOfFuture{virtualvoidSmile(){printf(":)");}};...voidmain(){Janus*j=newJanus();FaceOfFuture*future=j;FaceOfPast*past=j;future->Smile();past->Smile();deletej;}它按预期工作(输出
这个问题在这里已经有了答案:Protecteddatainparentclassnotavailableinchildclass?(4个答案)关闭5年前。谁能给我解释一下为什么(比如,“为什么语言是这样的?”)下面的代码在B::C::bar的第二行有一个编译错误?classA{public:structD{voidcall_foo(A&a){a.foo();}};protected:voidfoo(){}};classB:publicA{structC:publicA::D{voidbar(A&a,B&b){b.foo();//OKa.foo();//Error.Huh?call_fo
这个故事和我之前的故事相似question.所有支持C++11的GCC版本都具有这种行为。我找不到与我的测试用例有冲突的任何其他编译器。测试用例:structBaseFooWrapper{BaseFooWrapper(intqux){}};structFoo{Foo(BaseFooWrapper&foo):foo(foo){}BaseFooWrapper&foo;};structSomeFooWrapper:publicBaseFooWrapper{usingBaseFooWrapper::BaseFooWrapper;Foofoo{*this};};intmain(){SomeFoo
这个问题在这里已经有了答案:Inheritanceandmethodoverloading(1个回答)关闭6年前。这是我的代码classB{public:virtualvoidinsert(intt,intp)=0;voidinsert(intt){insert(t,0);}};classD:publicB{public:voidinsert(intt,intp){}};intmain(){Dd;d.insert(1);}这不会编译。当然,如果我在main中说d.B::insert(1),它会,但为什么这是不正确的呢?谢谢。
我曾经读过一个关于dynamic_cast问题的答案。dynamic_cast无法工作,因为基类没有虚方法。其中一个答案说,从没有虚方法的类派生通常意味着糟糕的设计。这个对吗?即使不利用多态性,我仍然看不出这样做有什么错误。 最佳答案 这取决于我们在谈论什么:对于Traits类(无数据)没问题(想到了std::unary_function)对于private继承(用于代替组合以从空基优化中受益)也很好当您开始以多态方式处理此类Derived对象时,问题就出现了。如果您达到了这样的位置,那肯定是代码味道。注意:即使上面提到的很好,您仍
我有一个真实的情况,可以用下面的例子来概括:templatestructNotifier{voidadd_listener(ListenerType&){}};structTimeListener{};structSpaceListener{};structA:publicNotifier,publicNotifier{};structB:TimeListener{};intmain(){Aa;Bb;a.add_listener(b);//whyisambiguous?return0;}为什么B对编译器来说并不明显?是TimeListener,因此唯一可能的重载解决方案是Notifie
我对vptr和内存中对象的表示不太困惑,希望您能帮助我更好地理解问题。考虑到B继承自A,并且都定义了虚函数f()。从我学到的知识,B类对象在内存中的表示形式如下:[vptr|A|B]以及vtbl指向的vptr包含B::f()。我还理解,将对象从B转换为A除了忽略对象末尾的B部分外,什么都没有做。是真的吗这不是错误的行为吗?我们希望A类型的对象执行A::f()方法,而不是B::f()。系统中是否存在与类数相同的vtables?从两个或多个类继承的类的vtable看起来如何?C的对象将如何在内存中表示?与问题3相同,但具有虚拟继承。 最佳答案
我需要有关使用接口(interface)的多重继承的实现的帮助...有一个现有的代码和一个具有很多功能的接口(interface)。这些实例是使用工厂创建的。classIBig{//Lotofpurevirtualfunctions};他的实现:classCBig:publicIBig{//Implementation}我想将界面拆分为多个较小的界面,但它应该在一段时间内与现有代码保持兼容。这是我尝试做的示例:classIBaseA{public:virtualvoidDoA()=0;};classIBaseB{public:virtualvoidDoB()=0;};//Thesame
我理解在使用多重继承时需要虚拟继承——它解决了可怕的菱形继承(钻石问题)。但是如果我不使用多重继承呢?是否需要虚拟继承?我似乎记得听说它对异常很重要(抛出派生类,通过基类引用捕获)。但是,虚拟析构函数是否足以满足此要求?我已经尝试搜索我曾经在这方面看到的引用页面,但我似乎找不到它。 最佳答案 您可能正在考虑这个Boost.Exceptionguideline,为了完整起见,我将在此处复制:在异常类型中使用虚拟继承异常类型在从其他异常类型派生时应该使用虚拟继承。这一见解归功于AndrewKoenig。使用虚拟继承可以防止异常处理程序中