2

派生类是否有任何主流语言的设计模式可以从基类继承代码并在派生类的范围内评估该代码? 例如(使用伪 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

4 回答 4

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++ 中,由于 yourBase是空的,实际上并不能保证sizeof(Base)> sizeof(Derived)--- 可以采用空基优化,使得法线Base(可能)是指针的大小,但Basea 的部分Derived实际上是空的. 大多数平台可能会为这样的空类分配 1 个字节,并且指针通常比这大,但没有指定。)

于 2013-05-15T15:02:09.020 回答
2

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

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
于 2013-05-15T15:38:31.657 回答
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
}

编辑:操作,这仅适用于静态类型。不是您问题的解决方案。

于 2013-05-15T20:17:47.047 回答
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)。但不能保证,这是一个不寻常的“功能请求”,我不太了解动态语言......

于 2013-05-15T14:55:38.760 回答