D成员函数属性

时间:2011-12-26 11:42:58

标签: class attributes d

考虑:

class B
{
public:
    int i = 4;
}

class A
{
public:
    B b;

    this()
    {
        b = new B;
    }

    ref B f()
    {
        return b;
    }
}

成员函数f前面的ref存储类是多余的吗?类对象总是通过引用传递,因此返回Bref B是等效的吗?

第二:pure成员函数?纯函数只返回依赖于参数的东西。因此它不应该依赖于类的任何数据成员,因为即使对于传入的相同参数,它们也可能更改函数的输出。因此,pure成员函数也是static成员函数? (反过来可能不是真的)

第三:const和不可变成员类之间有什么区别?要区分不可变和const类对象的成员函数调用?在语义上它是相同的,因为我们不能用两个属性改变数据成员,对吗?

第四:我应该添加尽可能多的功能属性吗?与pureconstimmutablenothrowfinal一样?


太棒了,刚发现这个有用:

inout(B) f() inout
{
    return b;
}

3 个答案:

答案 0 :(得分:5)

ref B f()是一个通过引用返回B的函数。 B是类引用。因此,它通过引用返回类引用。这在D中不是废话,因为类引用可以反弹:

auto a = new A;
a.f() = new B; // rebinds a.b, possible due to return by ref

同样,您也可以在D:

中指向类引用
class A
{
    B b;

    /* ... */

    B* f()
    {
        return &b;
    }
}

auto a = new A;
B* b = a.f(); // pointer to reference to instance of class B
*b = new B; // updates a.b

对于pure成员函数,隐式this引用参数就是 - 另一个参数。它被认为是输入的一部分。使用相同的this对象和相同的常规参数,输出仍然始终相同。


使用const成员函数,您不知道this对象是可变的还是不可变的。它可能是 - const成员函数承诺不会改变它。使用immutable成员函数,this对象始终是不可变的。因此,this引用可以作为不可变参数传递给另一个函数,或者分配给不可变变量。


在决定何时关注constimmutablepurenothrow时,您必须考虑在客户端代码中是否确实需要这些不同的保证。如果你正在编写一个通用的库,你可能不知道这个,所以在这些情况下,最好提供尽可能多的保证。

final的情况可以说是不同的。如果您不希望客户端代码意外覆盖无法覆盖的功能或者无意覆盖的功能,或者您希望为编译器提供更多机会来优化对该功能的调用,请使用它。不覆盖任何函数(使用override)并且不实现任何接口函数的最终函数不必是虚函数,从而减少了调用开销。

答案 1 :(得分:3)

  

成员函数f前面的ref存储类是多余的吗?类对象总是通过引用传递,因此返回Bref B是等效的吗?

添加ref可让您通过以下方式更改b字段(实际参考,而不仅仅是其内容):a.f() = new B();

  

第二:pure成员函数?

我相信纯方法只会将this视为另一个论点。

  

第三:const和不可变成员类之间有什么区别?要区分不可变和const类对象的成员函数调用?在语义上它是相同的,因为我们不能用两个属性改变数据成员,对吗?

是的,但immutable版本有更强的保证。

  

第四:我应该添加尽可能多的功能属性吗?与pureconstimmutablenothrowfinal一样?

使用您正在编写的代码时,添加尽可能多的属性将非常有用。 (请注意,当前实现在检测冗余属性方面不是很好。)

答案 2 :(得分:2)

  

所以返回B和参考B是等价的吗?

没有。 ref使函数返回左值,从而允许:

auto a = new A;
auto b = new B;
b.i = 55;
a.f() = b;
writeln(a.b.i); // 55

  

pure会员功能?

成员函数可以被视为一个自由函数,将实例作为参数之一。

   class A { pure void f(int others) immutable; }
<=>
   class A { ... }
   pure void f(immutable(A) this, int others);

因此,纯成员函数仍然可以读取和修改(对于弱纯的成员函数)this,因为它只是参数之一。


  

const和不可变成员类之间有什么区别?

不确定你是什么意思☺


  

我应该添加尽可能多的函数属性吗?

您应该添加最能描述您的功能的功能属性。如果该函数将从不被覆盖,则添加final。如果它从不抛出任何异常,则添加nothrow

如果函数是模板函数,则可以推断(BTW,purenothrow@safe。)