从函数返回对对象的静态常量引用
Returning static const reference to object from functions
在有效C++(第 18 项:使接口易于正确使用和难以正确使用)中,我看到了类似于以下内容的代码示例:
class Month
{
public:
static Month Jan()
{
return Month(1);
}
static Month Feb()
{
return Month(2);
}
//...
static Month Dec()
{
return Month(12);
}
private:
explicit Month(int nMonth)
: m_nMonth(nMonth)
{
}
private:
int m_nMonth;
};
Date date(Month::Mar(), Day(30), Year(1995));
更改函数以使它们返回对 Month 的静态常量引用是否有任何缺点?
class Month
{
public:
static const Month& Jan()
{
static Month month(1);
return month;
}
static const Month& Feb()
{
static Month month(2);
return month;
}
//...
static const Month& Dec()
{
static Month month(12);
return month;
}
private:
explicit Month(int nMonth)
: m_nMonth(nMonth)
{
}
private:
int m_nMonth;
};
我认为第二个版本比第一个版本更有效率。
原因1:它不是更好。
按值返回会产生复制整个对象的成本。
按引用返回会产生复制有效指针的成本,以及取消引用该指针的成本。
由于Month
是int
的大小:
- 复制
- 引用并不比复制
Month
快 - 每次访问该引用时都会发生取消引用。
因此,一般来说,通过 const 引用返回是一种优化,旨在防止代价高昂的副本。
原因2:static
使情况变得更糟
与 C 不同,C++承诺函数中的静态变量将在函数第一次调用时构造。
实际上,这意味着对函数的每次调用都必须以一些看不见的逻辑开头,以确定它是否是第一次调用。
另见沃恩·卡托的回答
另请参阅ildjam的评论
某些编译器不会内联包含静态局部变量的方法,内联是这里最重要的性能优化。
相关文章:
- 私有类型的静态常量成员
- 分离一个静态常量 std::thread?
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- 我可以在运行时重新定义在 OpenCascade/OCCT 标头中定义的 c++ 静态常量吗?
- 如何为静态常量模板化专用整数值分配存储
- 使用什么代替"静态常量 TCHAR *"
- C++ 模板中的静态常量初始化顺序
- 如何在编译时解析静态常量 std::string?
- 关于静态常量数据模因的声明和定义的混淆
- 将 static_cast<int>(-15) 分配给静态常量字符类型变量
- 为什么在第二类中使用静态常量会在第一类中给出编译器错误?
- 静态常量与常量局部变量,哪一个性能更好
- 如何在模板类中设置静态常量变量
- public:静态常量字符串声明/初始化问题
- 有没有办法声明一个公共静态常量,该常量将使用 constexpr 在源文件中定义(有什么区别)?
- 对静态常量积分类型的未定义引用
- 全局变量中的静态常量与常量
- c++ 类中的静态常量变量和常量变量在存储方面是否有区别
- 避免在静态常量类上定义但不使用
- 指向静态常量对象的共享指针?