这个条款或许改为 宁可编译器替换预处理器
比较好。
定义常量指针
有必要将指针(而不止是所指之物)声明为 const。
例如定义一个常量的 char*-based 的字符串,必须 const 两次。前一次是类型需要,后一次限制为常量。
const char* const Author="somebody";
FFunctionLibrary::Println(Author);//somebody
Author="anybody";//error:类型只可读
FFunctionLibrary::Println(Author);//anybody
当然使用 std::string 替换 const char* 更合适。
为了将常量的作用域(scope)限制在class内,你得让它成为 class 的一个成员(member),而为了确保常量至多只有一份实体。你必须让它成为一个static成员。(Moota:只是需求,不是常量必须为静态)
class ANonDefine
{
public:static const int ConstNumber=10;
};
但是你所看到的只是 ConstNumber 的声明式,而非定义式。通常情况下C++会要求对你所使用到的任何东西提供一个定义式,但也有特殊情况。
如果它是个class专属常量又是static且为整数类型(例如ints,chars,bools),只要不取它们的地址,可以直接声明并使用它们。除非如果坚持要取地址或者你的编辑器强制要求看到一个定义式,
class ANonDefine
{
public:static const int ConstNumber=10;
};
const int ANonDefine::ConstNumber=9;
注意上面的写法是错误的。
由于 static 只能定义被初始化一次,请把定义式放在实现(.cpp)文件
而非头(.h)文件。
由于常量已在声明时获得初值
,因此在定义它的时候不可以再设初值。
顺带一提的是我们无法利用 #define 去创建一个 class 专属常量,因为#define并不重视作用域
。一旦宏被定定义,它将在之后的编译过程中都有效(除非在某处被 #undef )。这也意味宏没有任何封装性,也就是指没有private #define,public #define。
当使用常量作为数组大小时,如下的代码是错误的
class ANonDefine
{
public:static const int ConstNumber;int Array[ConstNumber];
};
因为编辑器坚持在编译期知道数组的大小。
解决方法
class ANonDefine
{
public:enum {ArraySize=5};int Array[ArraySize];
};
其理论基础是:一个属于枚举类型的数值可以充当ints被使用。
enum hack 的行为某方面来说比较像 #define 而不是const,有时候这就是想要的,例如取一个 const 的地址是合法的,而取一个 enum 的地址是非法的,而取一个#define 的地址通常也不合法。如果不想别人指针或者引用自己某个整形常量,enum 可以实现这个约束。
#define容易误用
比如宏函数
#define Add(a,b) a+b
int main()
{FFunctionLibrary::Println(Add(1,2)*Add(3,4));//1system("Pause");return 0;
}
Add 宏函数执行 a+b 的行为,但宏只是文本替换,像上述的代码实际执行的是 1+2 * 3+4=11,而不是我们期望的(1+2)*(3+4)。这也就是说,你必须记住为宏中的所有实参加上小括号。
inline 而对于替换行为,更好的选择是使用 inline 函数(内联)。
template <typename T>
inline T AddUsingInline(const T& a,const T& b)
{return a+b;
}
有了const,enum,inline,我们对于预处理器(特别是 #define)的需求降低了,但并非完全消除。#include 仍然是必需品,而 #ifdef,#ifndef 也继续扮演着控制编译的重要角色。目前还没到预处理器全面退出的时候,但你应该明确地慎用它。
本文发布于:2024-01-31 15:48:11,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170668729429632.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |