继承:在派生类的范围内进行评估?

时间:2013-05-15 14:45:44

标签: java c++ oop design-patterns d

派生类是否有任何主流语言的设计模式从基类继承代码并在派生类的范围内评估该代码?例如(使用伪C ++语法):

class Base {
    // (How) can this be modified to be evaluated 
    // in the derived class's scope so that it
    // prints the size of the derived class?
    void printSize() {
        cout << sizeof(*this) << endl;
    }
};

class Derived : public Base {
    void* dummy;
};

int main() {
    Base base;
    Derived derived;
    base.printSize();  
    derived.printSize();  // Should be > base.printSize().
    return 0;
}

我意识到这可以用宏来完成,但是这需要在派生类的范围内显式地实例化宏。

编辑:为了澄清,本文的重点是我不想在每个派生类中手动重新实现printSize()或类似内容。我正在寻找一个聪明的模式来制作编译器/解释器(我很想知道是否有任何语言都有解决方案,即使我在我的例子中使用过C ++)也是这样做的。

编辑#2:我想在动态语言中这很容易。我对静态类型语言的解决方案更感兴趣,主要是C ++,Java和D.

编辑#3:模式应该适用于运行时类型,而不是编译时类型。因此,D的模板这个参数不是解决方案。

4 个答案:

答案 0 :(得分:2)

如果是“主流”,你包括主流脚本语言,如Perl或Python,那么是的。 Perl方法通常在派生最多的范围内被“评估”,因为Perl“对象”通常是一个哈希映射,并且来自继承树的所有级别的所有变量都在相同的“范围”中(即,键入到相同的哈希映射)。 Python类会发生类似的事情,尽管(IIRC)Python有一种方法可以创建一个符号,这个符号会被修改,以便根据编写代码的类来区分它们。当然,这些语言都没有“sizeof” “概念本身,所以你的具体例子不会特别相关。

在C ++中,基于它所调用的类型来决定成员函数的当前类的概念(就我所知)并不真正起作用。但是,您可能能够使用模板接近您所描述的内容。例如,像这样:

template<typename T>
void printSize( T &t ) {
    cout << sizeof(t) << endl;
}
int main() {
    Base base;
    Derived derived;
    printSize(base);
    printSize(derived);
}

(旁注:在C ++中,由于您的Base为空,实际上无法保证sizeof(Base)&gt; sizeof(Derived) ---可以采用空基优化,以便normal Base(也许)是指针的大小,但是Base的{​​{1}}部分实际上是空的。大多数平台可能会为这样的空类分配1个字节,而指针通常是大于此,但未指定。)

答案 1 :(得分:2)

D来救援。 Template mixins正是用于在目标上下文中进行评估的工具,您不需要任何特殊的类型层次结构(如果您需要,仍然可以添加一个):

http://dpaste.1azy.net/eec411e8

mixin template SizePrinter()
{
    static void printSize()
    {
        import std.stdio;
        writeln(__traits(classInstanceSize, typeof(this)));
    }
}

class Tested1
{
    int[64] dummy;
    mixin SizePrinter;
}

class Tested2
{
    int[16] dummy;
    mixin SizePrinter;
}

void main()
{
    Tested1.printSize();
    Tested2.printSize();
}

应用程序输出:

272
80

答案 2 :(得分:1)

在C ++中,我认为你会越接近奇怪的重复模板模式(CRTP),但它有严重的局限性:

template<typename T>
class Base {
    void printSize() {
        std::cout << sizeof(T) << std::endl;
    }
    void doSomething() {
        T::member_variable = 3;
        T::doSomethingElse();
    }
};

class Derived : public Base<Derived> {
public:
    int member_variable;
    void doSomethingElse() { ... }
};

您也可以使用虚拟方法,但它们要求您在每个派生类中重新实现该方法,所以我想这不是您想要的。

要真正实现您的想法,您可能需要一种动态语言(例如Python)。不过没有保证,这是一个不寻常的“功能请求”,我不太了解动态语言......

答案 3 :(得分:1)

D中有一个更好的解决方案,使用Template This Parameter

代码:http://dpaste.1azy.net/78810a79

import std.stdio;

class Base {
  int[64] dummy1;
  final static size_t getSize(this T)() {
    return __traits(classInstanceSize, T);
  }
}

class Derived : Base {
  int[16] dummy2;
}

void main() {
  writeln(Base.getSize());    // prints: 272
  writeln(Derived.getSize()); // prints: 336
}

编辑:Ops,这只适用于静态类型。不是你问题的解决方案。