【发布时间】:2010-12-24 08:40:49
【问题描述】:
(Objective C) 我如何使用派生指针调用基类函数,其中 foo 在派生类中被覆盖。基本上相当于这个 C++ 代码
base* b_ptr = 0 ;
derived* d_ptr = new derived() ;
d->base::foo() ;
我认为这应该相当简单。我需要使用选择器吗?
【问题讨论】:
标签: objective-c class pointers
(Objective C) 我如何使用派生指针调用基类函数,其中 foo 在派生类中被覆盖。基本上相当于这个 C++ 代码
base* b_ptr = 0 ;
derived* d_ptr = new derived() ;
d->base::foo() ;
我认为这应该相当简单。我需要使用选择器吗?
【问题讨论】:
标签: objective-c class pointers
您通常只能在类内部使用 super 关键字执行此操作
- (int)doSomething {
NSLog(@"calling doSomething on base class");
return [super doSomething];
}
但是,仍然可以使用运行时函数 objc_msgSendSuper 从类外部执行此操作,但有点棘手。
#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));
}
【讨论】:
你没有。 Objective-C 对面向对象的看法与 C++ 非常不同。这些不是“类函数”——它们是对象的方法。更重要的是,您不直接调用它们——您向对象发送消息,对象通过执行适当的方法来响应。如果一个类选择覆盖一个方法,那么这就是它的实例在接收到相应消息时将使用的实现。直接调用方法实现会破坏封装,如果没有一些丑陋的 hack,您将无法做到。
有一个有限的例外:在方法实现中,您可以使用两个名称来引用当前对象。如果你说[self doSomething],那么它会调用当前类的doSomething 方法。如果改为写[super doSomething],它将忽略自己的实现并使用超类的方法。
【讨论】: