Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在设计API时,如何使用const和volatile设计重载成员函数?_C++_Api - Fatal编程技术网

C++ 在设计API时,如何使用const和volatile设计重载成员函数?

C++ 在设计API时,如何使用const和volatile设计重载成员函数?,c++,api,C++,Api,假设您正在编写一个小型库或API,它将分发给其他程序, 这意味着您永远不知道其他程序员将如何创建对象:这样的对象是常量、volatile、const volatile还是仅仅是一个普通对象 通常,当我们声明某个类时,我们会这样做: class A // THIS CLASS DOES NOT SUPPORT ANYTHING { public: int get() { return x; } private: int x; }; 但是,如果希望类支持常量对象,将使用常量限定符重

假设您正在编写一个小型库或API,它将分发给其他程序, 这意味着您永远不知道其他程序员将如何创建对象:这样的对象是常量、volatile、const volatile还是仅仅是一个普通对象

通常,当我们声明某个类时,我们会这样做:

class A // THIS CLASS DOES NOT SUPPORT ANYTHING
{
public:
    int get() { return x; }
private:
    int x;
};
但是,如果希望类支持常量对象,将使用常量限定符重载成员函数:

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;
};
但若用户使用的对象是常量、易失性或 若用户将同时使用易失性和常量的对象,该怎么办? 那么我们也应该为它添加支持

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)中,我们可以证明我们的类能够被设置为任何类型的 这意味着其他编程人员在创建类的volatile、const或volatile const对象时不会有问题

我的问题是: 将每种方法重叠四次是一种好的设计实践吗? 若否,原因为何

另外,如果我们的类有20个方法,那么当您将它们全部重载时,它实际上会有80个方法

编辑:

现实世界中的API类会做这样的事情吗?
如果没有,那么如果我们有这样的需要,我们将如何创建该类的volatile或const volatile对象。

我的观点是,在现实世界中:

  • Volatile没有被广泛使用,当它被使用时,它总是修改基本类型。但决不使用对象,因此您永远不需要重写易失性成员函数

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

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

    b。然后,问问自己,函数所做的这件事是否改变了对象的可观察状态。如果是,那么函数不应该是常量。如果它不是,则将其声明为常量

  • 当客户机代码想要使用您的类时,当不允许修改对象的状态时,它将有一个
    const
    引用,所有这些都将正常工作


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

    我的观点是,在现实世界中:

  • Volatile没有被广泛使用,当它被使用时,它总是修改基本类型。但决不使用对象,因此您永远不需要重写易失性成员函数

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

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

    b。然后,问问自己,函数所做的这件事是否改变了对象的可观察状态。如果是,那么函数不应该是常量。如果它不是,则将其声明为常量

  • 当客户机代码想要使用您的类时,当不允许修改对象的状态时,它将有一个
    const
    引用,所有这些都将正常工作


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

    拥有一个
    const
    对象是可行的,但我怀疑
    volatile
    会有很多用途。另外,对于简单的getter之类的东西,我总是让我的方法保持常量。正如您所说的:“我怀疑volatile会有很多用途”,至少其中一个可能希望这样,还有“我总是让我的方法保持常量”,如果该方法必须更改内部成员该怎么办?不可能所有的方法都是常量,这样的类就是useles:DI意味着我总是使用简单的、不可修改的方法,const.)拥有一个
    const
    对象是可行的,但我怀疑
    volatile
    是否有很多用途。另外,对于简单的getter之类的东西,我总是让我的方法保持常量。正如您所说的:“我怀疑volatile会有很多用途”,至少其中一个可能希望这样,还有“我总是让我的方法保持常量”,如果该方法必须更改内部成员该怎么办?不可能所有的方法都是常量,这样的类就是useles:DI意味着我总是使用简单的、不可修改的方法,const.)有时指向对象的指针是可变的(volatile通常与内置类型一起使用),这并不要求您的方法是可变的。我从来没有见过那些不稳定的修饰语有什么用处(当然除外)。@AlexandreC说Alexandrescu技术是对一个几乎无用的语言特性的巧妙滥用。太酷了!有时指向对象的指针是可变的(volatile通常与内置类型一起使用),这并不要求您的方法是可变的。我从来没有见过那些不稳定的修饰语有什么用处(当然除外)。@AlexandreC说Alexandrescu技术是对一个几乎无用的语言特性的巧妙滥用。太酷了!