2012-01-19 23 views
1

我们假设你正在编写一个小型库或一个将分发给其他程序的API,这意味着你永远不知道其他程序员将如何创建对象:这样的对象是const,volatile还是const volatile,或者它只是一个普通的对象。如何在设计API时用const和volatile设计重载成员函数?

normaly当我们声明一些类,我们愿意这样做:

class A // THIS CLASS DOES NOT SUPPORT ANYTHING 
{ 
public: 
    int get() { return x; } 
private: 
    int x; 
}; 

但是,如果你想你的类支持const对象变成你重载成员函数与常量qualificator:

class B // THIS CLASS SUPPORTS CONST OBJECTS 
{ 
public: 
    int get() { return x; } 
    int get() const { return x; } 
private: 
    mutable int x; 
}; 

更多也许我们也想支持volatile,但不支持我们的类的const:

class C // THIS CLASS SUPPORTS VOLATILE OBJECTS 
{ 
public: 
    int get() { return x; } 
    int get() volatile { return x; } 
private: 
    int x; 
}; 

但如果用户将使用常量或易失性对象,或者如果用户将同时使用volatile和const对象,该怎么办? 那么我们也应该加入对它的支持!

class D // THIS CLASS SUPPORTS CONST, VOLATILE AND CONST VOLATILE OBJECTS 
{ 
public: 
    int get() { return x; } 
    int get() const { return x; } 
    int get() volatile { return x; } 
    int get() const volatile { return x; } 
private: 
    mutable int x; 
}; 

现在让我们看看为什么要我们班有那些4个重载:

// EXAMPLE 
int main() 
{ 
    // figure 1 
    const A a ; 
    a.get(); // ERROR 

    // figure 2 
    volatile B b; 
    b.get(); // ERROR 

    // figure 3 
    const volatile C c; 
    c.get(); // ERROR 

    // figure 4 where we finaly created a super class capable of anything!! 
    const volatile D d; 
    d.get(); // NOW IS OK! 

    cin.ignore(); 
    return 0; 
} 

以及在最后的例子(图4),我们可以进行岸,我们班是能够被instatated 任何类型 这意味着其他程序员将不会有问题来创建类的volatile,const或volatile const对象!

我的问题是: 四次叠加每种方法是否是一种很好的设计方法? 如果不是为什么不呢?

如果我们的班级有20个方法,那么当您将所有的方法重载时,它们都会有80个方法!

编辑:

没有现实世界的API类做这种事?如果不是,那么如果我们说我们有这样的需求,那么我们将如何创建该类的volatile或const volatile对象。

+2

有一个'const'对象是可行的,但我怀疑会有很多'volatile'的用法。而且,对于像简单的getter这样的东西,我总是会让我的方法成为'const'。 –

+0

正如你所说:“我怀疑会有很多volatile的用法”,至少他们中的一个可能会这么想,也是“我总是让我的方法为const”,以及如果该方法必须改变内部成员呢?所有的方法不能是const,这样的类将是useles:D – codekiddy

+0

我的意思是我总是让我简单的,非修改的方法,const。 :) –

回答

4

我的看法是,在现实世界中:

  1. 挥发性没有被广泛使用,而当它总是修改基本类型。但从来没有对象,所以你永远不需要重写一个volatile成员函数。

  2. const应该添加到成员函数中,而不是考虑const客户端代码是否需要它,但是应该考虑成员函数的操作在概念上是否是常量。这就是所谓的const正确性

    a。首先,该功能应该只做一件事。也许是一件复杂的事情,但可以描述为一个单一的概念。

    b。然后,问问你自己这个函数是否改变了对象的可观察状态。如果是这样,那么函数不应该是恒定的。如果没有,那么就声明它是不变的。

当客户端代码想使用你的类,它有一个const引用时,不允许它修改对象的状态,一切都将只是工作。

请注意,我谈到了对象的可观察状态,而不是成员变量的实际内容:这是一个实现细节。

+3

有时*指向对象的指针是不稳定的(volatile最常用于内置类型),并且这不要求你的方法是不稳定的。我从来没有看到这些易变修饰符的用法(当然,除了http://drdobbs.com/cpp/184403766)。 –

+0

@AlexandreC Al​​exandrescu技术是一种非常无用的语言功能的智能滥用。非常酷! – rodrigo

+0

罗德里戈感谢您的帮助,亚历山大感谢您的链接! – codekiddy