如何在设计API时设计带有const和volatile的重载成员函数
how to design overloaded member functions with const and volatile while designing API?
假设您正在编写一个小型库或API,该库或API将分发给其他程序,这意味着你永远不知道其他程序将如何创建对象:这样的对象是const、volatile、const-volatile还是只是一个普通的对象。
正常情况下,当我们声明某个类时,我们会这样做:
class A // THIS CLASS DOES NOT SUPPORT ANYTHING
{
public:
int get() { return x; }
private:
int x;
};
但是,如果您希望您的类支持const对象,您将使用const限定符重载成员函数:
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;
};
但是,如果用户将使用const或volatile或若用户将同时使用一个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),我们可以确信我们的类能够被实例化为任何类型的这意味着其他程序员在创建类的volatile、const或volatile const对象时不会有问题!
我的问题是:将每种方法重叠四次是一种好的设计实践吗?如果不是,为什么不呢?
如果我们的类有20个方法,那么当你重载它们时,它实际上会有80个方法!
编辑:
现实世界中的API类会做这样的事情吗?如果没有,那么如果我们有这样的需求,我们将如何创建该类的volatile或const-volatile对象。
我的观点是,在现实世界中:
-
Volatile并没有被广泛使用,当它被使用时,它总是修改基本类型。但是永远不要对象,所以您永远不需要重写volatile成员函数。
-
const
应该添加到成员函数中,而不是考虑const
客户端代码是否需要它,而是考虑成员函数所做的操作是否在概念上是恒定的。这被称为常量正确性:a。首先,函数应该只做一件事。也许是一件复杂的事情,但可以作为一个单一的概念来描述。
b。然后,问问自己函数是否改变了对象的可观察状态。如果是,那么函数就不应该是常量。如果没有,则声明它为常量。
当客户端代码想要使用您的类时,当不允许修改对象的状态时,它将具有const
引用,所有这些都将正常工作。
注意,我讨论了对象的可观察状态,而不是成员变量的实际内容:这是一个实现细节。
- 继承函数的重载解析
- 你能重载对象变量名本身返回的内容吗
- 从父命名空间重载类型
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 重载操作程序时出错>>用于类中的字符串 memebr
- 一个关于在C++中重载布尔运算符的问题
- 不同翻译单元中不可重载的非内联函数定义
- 为什么使用SFINAE而不是函数重载
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 将重载的成员函数传递给函数模板
- c++:可变模板和函数重载
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 重载==不适用于二进制树
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 正在尝试重载二进制搜索树分配运算符
- 如何在设计API时设计带有const和volatile的重载成员函数
- const和volatile的重载——为什么它可以通过引用工作