Prefer const, enums, and inlines to #defines
#define ASPECT_RATIO 1.653
// 1. Never been seen by compilers, removed by the preprocessor
// 2. ASPECT_RATIO not get entered into the symbol table
// 3. Multiple copies of 1.653 in object code by preprocessor
const double AspectRatio = 1.653;
// 1. Seen by compilers
// 2. Get entered into the symbol table
// 3. Smaller code: never result in more than one copy
// 4. No storage for const objects of integral types, unless create a pointer or ref
const char * const strName = "Gary Hsieh";
// const pointer to const char
#include <string>
const std::string stdStrName = "Gary Hsieh";
// std::string object are generally preferable to char*-based progenitor.
/* About class-specific constants */
class GamePlayer {
private:
static const int NumTurns = 5;
// 1. A declaration, not a definition
// 2. Usally need a definition, constant that are static and of integral type(e.g., int, bool, char) are an exception
// 3. If not take address, can provide no definition
int scores[NumTurns];
};
const int GamePlayer::NumTurns;
// 1. Need address or compiler incorrectly insist on a definition
// 2. Put in implementation file
// 3. No initial value is permitted, because declaration has one
class DefineInClass {
int wrong[SOME_NUM];
// compiler error
private:
#define SOME_NUM 123
// 1. #define don't respect scope: if defined, will be in force for the rest of the compilation
// 2. no private define
int correct[SOME_NUM];
};
class CostEstimate {
private:
static const double FudgeFactor;
};
const double CostEstimate::FudgeFactor = 1.35;
// For compilers don't accept the syntax above
/* Enum Hack */
class GamePlayer {
private:
enum { NumTurns = 5 };
int scores[NumTurns];
// If compilers insist knowing NumTurns and declaration with initial value is not accepted
};
// 1. Behave like #define: can not take address
// 2. No unnecessary memory allocation
// 3. Lots of code employs it and a fundamental technique of template metaprogramming
/* Macros -> functions */
#define CALL_WITH_MAX(a,b) isdigit((a) > (b) ? (a) : (b))
// 1. Don't incur the overhead of a function call
// 2. Remember to parenthesize
int a = 5, b = 0;
bool x = CALL_WITH_MAX(++a, b); // a is incremented twice
bool y = CALL_WITH_MAX(++a, b + 10); // a is incremented once
template<typename T>
inline void callWithMax(const T& a, const T& b) {
isdigit(a > b ? a : b);
}
// 1. Template for an inline function
// 2. Efficiency of a macro, predictable behavior(no need to parenthesize), type safety
// 3. Obeys scope and access rules, e.g., private in a class
沒有留言:
張貼留言