- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
最近,我一直在养成一种习惯,将我的代码中的许多东西作为const
:
(1) 函数参数,我知道永远不会改变。例如:
void foo (const int i, const string s)
^^^^^ ^^^^^
(2) 返回类型作为const
。例如:
struct A {
...
const int foo () { return ...; }
^^^^^
operator const bool () const { return ...; }
^^^^^
};
(3) 整数或字符串的简单计算。例如:
const uint size = vec.size();
^^^^^
const string s2 = s1 + "hello ";
^^^^^
...还有其他一些地方。通常在其他现实世界的代码中,我看不到标记为 const
的这种小规模变量。但我认为,让它们成为 const
永远不会有坏处。这是一个好的编程习惯吗?
最佳答案
(1) 和(3) 密切相关。按值参数只是一个具有该名称的局部变量,就像您的计算结果一样。
通常,无论您是否将局部变量标记为const
,在短函数中都没有什么区别,因为您可以直接看到它们的整个作用域。您可以看到值是否发生变化,您不需要或不希望编译器强制执行它。
不过,有时它确实有帮助,因为它可以防止您意外地将它们传递给通过非常量引用获取其参数的函数,而没有意识到您正在修改变量。因此,如果您在变量的生命周期内将其作为函数参数传递,则将其标记为 const
可以让您更有信心知道它之后的值是什么。
偶尔,将变量标记为 const
可以帮助优化器,因为您告诉它该对象永远不会被修改,有时这是真的,但编译器可以否则证明它。但出于这个原因可能不值得这样做,因为在大多数情况下它没有什么区别。
(2) 是另一回事。正如其他人所解释的那样,对于内置类型,它没有区别。对于类类型,不要按常量值返回。这似乎是个好主意,因为它可以防止用户编写一些毫无意义的东西,例如 func_returning_a_string() += "extra text";
。但它也阻止了一些有意义的事情——C++11 移动语义。如果 foo
返回一个 const 字符串,我写 std::string s = "foo";如果(条件)s = foo();
,那么我在 s = foo();
处获得复制分配。如果 foo
返回一个非常量字符串,那么我得到移动赋值。
类似地,在没有移动语义的 C++03 中,它防止了被称为“swaptimization”的技巧 - 使用非常量返回值我可以编写 foo().swap(s);
而不是 s = foo();
。
关于c++ - 尽可能多地维护 "const-ness"是个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8532095/
我正在尝试使用新的 c++17 类模板推导,在我应用 const 之前它似乎一切正常。这是我面临的麻烦的一个小例子: #include template struct X { T _dat
我正在使用整洁的 fmt 库,在其版本 8 中,如果编译器支持相关功能,则会对其格式字符串进行编译时检查。 在某个时候,我想编写以下代码: throw my_exception("error: {}"
我有一些实现图形算法的代码;特别是,有这些片段会导致问题: class Path{ private: const Graph* graph; public: Path(Graph* g
void foo (void *p); // library function; can't edit template void Remove (T *p) { // main code f
class Foo{}; class BarParent { Foo* p_foo; public: BarParent(Foo * const p_x) //OR BarPa
考虑以下 C++ 代码: typedef std::string& mutable_string_ref; const std::string str = "abc"; mutable_string_
我正在尝试从变量 (char*) 中移除常量特性,但出于某种原因,当我尝试更改值时,常量变量的原始值仍然保持不变。 const char* str1 = "david"; char* str2 =
我正在运行目标:tomcat:deploy。没有错误,但它没有将我的项目部署到 tomcat 中。我注意到这条消息: [INFO] Skipping non-war project 什么定义了我的项目
出于各种原因,我正在寻找一种方法来捕获传递给函数的参数的constexpr-ness。解释起来有点棘手,所以我认为代码最能展示我想要实现的目标 #include // For std::size_t
如果我创建了一个 C 模块,它向用户提供一个指向前向声明结构的句柄,如下所示: typedef struct FOO_Obj *FOO_Handle; 如果我然后声明将其用作 const 限定参数的函
我有两个结构: // ----- non-const ----- struct arg_adapter { EArgType type; // fmtA, fmtB, ...
为什么 width 在第一次实例化后不保持其 constness? template class ProjectionTest { std::array _arr; public: P
给定: template inline bool f( T n ) { return n >= 0 && n = 0 is always true 当 T 是 unsigned 类型时,有什么聪明
在最坏的情况下,从已知列表创建二叉树的时间复杂度为 O(n2),但平均情况为 O(n logn)。最坏情况和平均情况之间的差异取决于树在创建后的不平衡程度。如果 maxDepth == n,那么这是最
我有一个对象,在最基本的层面上看起来像这样: #include class x_link { public: x_link() { d
我偶然发现了一些看似正确的代码。它应该提供一个公共(public)的、不可变的指针,同时将可修改的非常量指针保持私有(private)。 奇怪的是,这段代码在 SN C++ 编译器(适用于 PlayS
This page说make_optional C++17 中的函数返回 constexpr optional .我认为(虽然我可能是错的)这需要 optional有一个 constexpr复制或移动
我已经编写了以下代码来测试跨函数调用的 noexcept 传播,它似乎并没有像我想象的那样工作。在 GCC 4.7.2 中,可以有效地测试函数是否为 noexcept 仅直接或作为模板特化参数传递时;
最近,我一直在养成一种习惯,将我的代码中的许多东西作为const: (1) 函数参数,我知道永远不会改变。例如: void foo (const int i, const string s)
我有一个关于 POD-ness 的问题。我预计如果 B 是非 POD 而 B 是 A 的成员,那么 A 也是非 POD。但是,以下代码示例输出“10”,因此 B 被正确地视为非 POD,但 A 是。
我是一名优秀的程序员,十分优秀!