Class 在类和结构之间选择

Class 在类和结构之间选择,class,polymorphism,d,struct,Class,Polymorphism,D,Struct,msdn关于C#的一篇文章给出了以下建议: 如果 类型很小,通常寿命很短,或者通常嵌入到 其他物体 除非类型具有以下所有特性,否则不要定义结构 特点: It logically represents a single value, similar to primitive types (整数、双精度等) 如果不满足其中一个或多个条件,请创建引用 类型而不是结构。如果不遵守此指南,则可能 对绩效产生负面影响 我想知道D的答案是什么。到目前为止,我只是在所有不需要多态性的情况下使用了结构。我不知道

msdn关于C#的一篇文章给出了以下建议:

如果 类型很小,通常寿命很短,或者通常嵌入到 其他物体

除非类型具有以下所有特性,否则不要定义结构 特点:

It logically represents a single value, similar to primitive types
(整数、双精度等)

如果不满足其中一个或多个条件,请创建引用 类型而不是结构。如果不遵守此指南,则可能 对绩效产生负面影响


我想知道D的答案是什么。到目前为止,我只是在所有不需要多态性的情况下使用了结构。我不知道尺寸是否也是一个考虑因素。或者其他任何东西。

结构是按值传递的,因此大小确实是一个考虑因素(尽管可以使用
ref
中的
避免)

大多数情况下,当您只需要按值传递时(对对象的更改不应传播),或者它是一个寿命短到足以保留在堆栈上的短期对象时,您应该使用结构(如
std.algorithm
模块中看到的范围对象;那里的所有函数几乎都返回结构)


就我个人而言,我已经为数据对象(单值子句)定义了结构,如2d点和角度,并为它们定义了一些方便的函数和运算符重载

相同的建议通常适用于D,就像在C中一样——它们的概念基本相同


唯一的例外是装箱建议——它不适用,因为装箱在D中并不是本机存在的。

在D中,装箱与C有一些关键区别,这使得更频繁地使用
struct
成为习惯用法:

  • 没有自动装箱,因为它解决的问题通常是通过模板解决的

  • 目前,垃圾收集器的效率较低

  • 如果您需要引用语义,那么指向结构的指针在大多数情况下都能很好地工作。(唯一的主要例外是指向具有重载算术或索引运算符的结构的指针的行为异常,因为这些操作被视为指针算术,而不是调用运算符重载。)此外,可以使用
    new
    运算符轻松地对结构进行堆分配

  • 结构可以有确定性析构函数(不定式)、复制构造函数等,因此可以用C++来实现类似的魔术。

    我想说,结构应该在任何时候使用,你不需要多态性,将来也不需要它,也不需要引用语义,或者如果你需要确定性销毁、复制构造等。如果你需要多态性,那么你肯定需要使用类


    如果您不需要多态性,但需要引用语义,那么指向堆分配结构的指针或最终类都可以正常工作。最后一个类在语法上稍微好一点,在重载算术运算符时不会遇到奇怪的情况。结构通过没有vtable或monitor避免了几个字节的开销。如果这两个建议对你都不重要,那么这只是个人偏好的问题。

    我想说,这一建议绝对不适用于D

    结构是值类型。类是引用类型。结构通常在堆栈上(尽管它们可以在堆上并用指针指向)。类在堆上。结构没有继承或多态性。类具有继承性和多态性

    在D中使用结构是非常常见的。我认为一般的规则是,如果某个东西不需要具有多态性,那么它应该是一个结构。选择类而不是结构的主要原因是希望继承和多态性

    第二个原因是,如果类型是引用类型更有意义(例如,容器可能应该是类,因为每次将其传递给函数时复制它是不好的)。结构可以具有引用语义,但使用类来实现这一点更为简洁

    最后,如果一个类型中包含大量数据,并且在将其传递给函数时不需要它的副本,那么将其作为类并仅在实际需要时复制它会更有效(尽管您可以选择始终通过ref传递它)

    D的结构肯定比C的结构更奇特,因为它们有析构函数和。D中也没有自动装箱问题,因为D使用模板(类似于C++,尽管它更强大,更容易使用)而不是泛型。如果你需要一个指向结构的指针,这很容易做到。所以,我真的不认为C的建议适用于D

    在我看来,C#建议源自两个问题:

  • 结构是值类型,因此具有值语义
  • 事实上,C#中的结构必须处理自动装箱,并且必须非常担心复制的成本
  • 结构也是D中的值类型,但是如果您愿意,它们的功能足够强大,可以具有引用语义,并且添加postblit构造函数和析构函数使它们的用途远远超过了在C#中使用结构所能做的。由于D没有自动装箱,关于自动装箱的担忧不适用于D。你仍然不希望你的结构是巨大的,因为除非你通过ref传递,否则每当你把它们传递给函数时,它们都会被复制,但这绝对不是像C#中那样大的担忧。在这方面,它与C++更加一致。 关于不变性的建议根本不适用于D。D结构经常是可变的,如果它们不是可变的,这将是一个大问题。例如,范围通常被实现为结构,如果不能对其进行变异,这是不可能的

    所以,不,我不认为C#建议真的适用于D
    It has an instance size smaller than 16 bytes.
    
    It is immutable.
    
    It will not have to be boxed frequently.