【问题标题】:Calling base class functions through derived pointers通过派生指针调用基类函数
【发布时间】: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


    【解决方案1】:

    您通常只能在类内部使用 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));
    }
    

    【讨论】:

    • 谢谢。我没有想到看运行时间来完成这个任务。看来我还有很多东西要学。
    • 那是因为您不应该查看运行时来完成此任务。使用内部方法调度函数来规避语言应该工作的方式是令人讨厌的。精心设计的代码永远不需要这样做。
    【解决方案2】:

    你没有。 Objective-C 对面向对象的看法与 C++ 非常不同。这些不是“类函数”——它们是对象的方法。更重要的是,您不直接调用它们——您向对象发送消息,对象通过执行适当的方法来响应。如果一个类选择覆盖一个方法,那么这就是它的实例在接收到相应消息时将使用的实现。直接调用方法实现会破坏封装,如果没有一些丑陋的 hack,您将无法做到。

    有一个有限的例外:在方法实现中,您可以使用两个名称来引用当前对象。如果你说[self doSomething],那么它会调用当前类的doSomething 方法。如果改为写[super doSomething],它将忽略自己的实现并使用超类的方法。

    【讨论】:

      猜你喜欢
      • 2016-10-06
      • 1970-01-01
      • 2012-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 2014-04-18
      • 1970-01-01
      相关资源
      最近更新 更多