2011-12-26 109 views
3

考虑:d成员函数属性

class B 
{ 
public: 
    int i = 4; 
} 

class A 
{ 
public: 
    B b; 

    this() 
    { 
     b = new B; 
    } 

    ref B f() 
    { 
     return b; 
    } 
} 

裁判存储类中的成员函数f的前面是多余的吗? Class对象始终按引用传递,因此返回Bref B是否等同?

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

第三:const和不可变成员类有什么区别?区分不可变和const类对象的成员函数调用?在语义上,它是平等的,我们不能改变这两个属性的数据成员,对吧?

第四:我应该添加尽可能多的功能属性吗?像pureconstimmutable,nothrowfinal


真棒,刚发现这工作:

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

回答

5

ref B f()是一个通过引用返回B的函数。 B是类参考。 Ergo,它通过引用返回一个类的引用。这不是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)并且不实现任何接口函数不一定是虚函数,从而减少通话开销。

+0

在完美模块化代码的情况下,所有的功能将是纯粹的? – 2011-12-26 18:17:13

+1

@Daevius,你不能从纯函数中调用不纯的函数。这排除了系统调用以及取决于它们的一切。我认为,通过这个衡量标准,你的代码永远不会“完美”模块化,它总是依赖于某种单一的行为。 – 2011-12-26 19:05:10

+0

有关'pure'的更多信息,请参阅以下最近的问题:http://stackoverflow.com/questions/8572399/how-is-this-pure-function-able-to-modify-non-private-state – 2011-12-27 00:32:29

2

于是久违B和REF 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,因为它仅仅是参数之一。


就是一个常量和一个不变的成员类之间的区别?

不知道你是什么意思☺


我应该添加尽可能多的功能属性越好?

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

(顺便说一句,purenothrow@safe可如果函数是一个模板函数推断。)

3

裁判存储类在成员函数f的前面是多余的权利? Class对象始终按引用传递,因此返回Bref B是否等同?

添加ref允许您通过写作来改变b场(实际的参考,而不只是它的内容):a.f() = new B();

二:pure成员函数?

我相信纯方法把this当作另一个论点。

第三:const和不可变成员类有什么区别?区分不可变和const类对象的成员函数调用?在语义上,它是平等的,我们不能改变这两个属性的数据成员,对吧?

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

第四:我应该添加尽可能多的功能属性吗?像pureconstimmutable,nothrowfinal

添加尽可能多的属性,因为使用您正在编写的代码时会很有用。 (请注意,目前的实现不太擅长检测冗余属性。)