Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I'm editing out my hints on the answering, since I completed the mission ;-)</p> <p>I am not an Objective-C programmer, but driven by curiosity I couldn't help wondering what's going on and played with the code a bit. What I've found out that the problem surfaces after commenting out everything but <code>Foo*</code> and <code>Bar*</code> parts and adding the following line to the <code>main()</code>:</p> <pre><code>Bar_objc *bo = [[Bar_objc alloc] init:(Bar_cpp*)0]; </code></pre> <p>After playing a bit I figured that it must have something to do with not quite defined result of the <code>alloc</code> message. Which is fixed by splitting the assignment above in two:</p> <pre><code>Bar_objc *bo = [Bar_objc alloc]; [bo init:(Bar_cpp*)0]; </code></pre> <p>That works just fine. So does casting the <code>alloc</code> results (see the code below). Alternatively, this can be fixed (I believe) with different names for initializers. Maybe also reimplementing <code>alloc</code>. No idea.</p> <p>The full code with multiple inheritance (it has some other minor changes - I've changed class/public pairs to structs for brevity, removed calling virtuals in constructors, changed <code>delete</code> invocations to <code>dealloc</code> messages, maybe something else):</p> <pre><code>#include &lt;iostream&gt; #import &lt;Foundation/Foundation.h&gt; struct Foo_cpp { virtual void foo() = 0; }; struct Bar_cpp { virtual void bar() = 0; }; @interface Foo_objc : NSObject { Foo_cpp* foo_cpp_; } - (id)init:(Foo_cpp*)foo; - (void)do_foo; @end @implementation Foo_objc : NSObject { Foo_cpp* foo_cpp_; } - (id)init:(Foo_cpp*)foo { if( self = [super init] ) foo_cpp_ = foo; return self; } - (void) do_foo { std::cout &lt;&lt; "do_foo: "; foo_cpp_-&gt;foo(); } @end @interface Bar_objc : NSObject { Bar_cpp* bar_cpp_; } - (id)init:(Bar_cpp*)bar; - (void)do_bar; @end @implementation Bar_objc : NSObject { Bar_cpp* bar_cpp_; } - (id)init:(Bar_cpp*)bar { if( self = [super init] ) bar_cpp_ = bar; return self; } - (void) do_bar { std::cout &lt;&lt; "do_bar: "; bar_cpp_-&gt;bar(); } @end struct Main : public Foo_cpp, public Bar_cpp { Foo_objc* foo_; Bar_objc* bar_; Main() { foo_ = [(Foo_objc*)[Foo_objc alloc] init:this]; bar_ = [(Bar_objc*)[Bar_objc alloc] init:this]; } ~Main() { [foo_ dealloc]; [bar_ dealloc]; } virtual void foo() { std::cout &lt;&lt; "foo" &lt;&lt; std::endl; } virtual void bar() { std::cout &lt;&lt; "bar" &lt;&lt; std::endl; } }; int main() { Main m; [m.foo_ do_foo]; [m.bar_ do_bar]; } </code></pre> <p>The result:</p> <pre><code>do_foo: foo do_bar: bar </code></pre> <p>The bottom line: I take it due to somewhat weak typing and possibility to send messages to the objects regardless of types, it's better to have no messages with the same name, but different parameters.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload