views:

131

answers:

2

( Objective C ) How would I call a base class function using a derived pointer where foo is overridden in the derived class. Essentially the equivalent of this C++ code

base* b_ptr = 0 ;
derived* d_ptr = new derived() ;
d->base::foo() ;

I would think this should be fairly simple. Do I need to use a selector?

+2  A: 

You don't. Objective-C's view of object-orientation is very different from C++'s. These are not "class functions" — they're methods of objects. More to the point, you don't call them directly — you send a message to an object and the object responds by executing an appropriate method. If a class chooses to override a method, then that is the implementation its instances will use when it receives the corresponding message. Directly calling a method implementation breaks encapsulation, and you can't do it without some ugly hacks.

There's one limited exception: Within a method implementation, there are two names you use to refer to the current object. If you say [self doSomething], then it will call the current class's doSomething method. If instead you write [super doSomething], it will ignore its own implementation and use the superclass's method.

Chuck
+1  A: 

You would normally only do this from inside the class, using the super keyword

- (int)doSomething {
    NSLog(@"calling doSomething on base class");
    return [super doSomething];
}

However, it's still possible to do it from outside the class using the runtime function objc_msgSendSuper, but it's a bit more tricky.

#import <objc/objc-runtime.h>

...

Derived *d = [Derived new];

// call doSomething on derived class
[d doSomething];

// call doSomething on base class
struct objc_super b = {
    .receiver = d,
    .class = class_getSuperclass([d class])
};
objc_msgSendSuper(&b, @selector(doSomething));
}
Zydeco
Thanks. I did not think of looking at the run time to accomplish this task. Looks like I have much to learn.
Steve
That's because you *shouldn't* look at the runtime to accomplish this task. Using the internal method dispatch functions to circumvent the way the language is supposed to work is nasty. Well-designed code will never, ever need to do this.
Chuck