C++ try not to use hashdefine but to replace it with const enum inline.

  • 2020-04-01 21:29:11
  • OfStack

For example, the program file begins with the following #define statement

 
#define N 10 
#define PI 3.14 
#define MAX 10000 
#define Heigth 6.65 
... 
... 


Assuming that there is an error in the program, and that it is before we use these constants, the editor should throw an error message. If the message says 6.65 there's an error here, Ok if you're lucky and you happen to remember or if the program is simple and you can see at a glance what 6.65 means, if the program is complicated and the file that says 6.65 refers to that file and you don't remember, then you're going to be confused as to what is this? Maybe spend a lot of time tracking what 6.65 is? Then locate the problem.
Why is the error message 6.65? Instead of Heith? Since the Heigth was replaced with 5.65 during the precompile phase,Height did not go into the system table. The solution is to use the following statement instead
Const double treeHeight = 5.68;
As a language constant, treeHeight is definitely known by the compiler and goes into the notation. The error reported is not a number but a variable name, which helps locate the problem.
There are two special cases for constant #define.
The first is to define constant Pointers. Here, the pointer is defined as a constant pointer, which also points to a constant, so it is in the following form:
Const char * const HZ="Hang Zhou";
In C++, it is better to replace the char* form with a string object:
Const STD ::string HZ ("Hang Zhou");
The second thing to note is the class exclusive constant. First restrict the action to a class and you must declare it as a member. Second, make sure that this constant has at most one entity, and you must make it a static member. Such as:
 
class People 
{ 
private: 
static const int Number=10; 
int phoneNumbers[Number]; 
...... 
} 

This is a declaration, not a definition. Usually C++ requires you to provide a definition of anything you use. Or use enum, and for macros of formal functions, use inline or template if possible. However, if it is a class exclusive constant and static and of integer type (int,char,bool), it needs special handling. As long as you don't marry their addresses, you just declare them instead of providing a definition. But if you take the address of a class exclusive constant, even if you don't take its address the compiler requires you to provide the definition.
The static const int People: : Number
The definition does not set the initial value because the initial value was already obtained when the declaration was made.

Here you can use enum to accomplish a similar function
 
class People 
{ 
private: 
enum { Number = 10 }; 
int phoneNumbers[Number]; 
.... 
} 

Enum is more like #define than const. Since it is legal to take the address of const, it is illegal to take the address of an enum, and it is often illegal to take the address of #define. So you can use enum to prevent others from getting the address of a constant.

Here is a paper test topic
 
#define PRODUCT(a,b) a*b 
.... 
int a=5,b=3,c; 
c=PRODUCT(a+3,b+4); 

So what is the value of c? C =5+3*3+4=18 instead of the programmer's expectation of 56, you must write this if you want to achieve the desired result

# define the PRODUCT (a, b) ((a) * (b))
Maybe you'll insist on writing macro functions, because you want to say that you can do the product of int,flaot,double, and so on by just writing a macro function. So let's look at the following example

# define MAX (a, b) ((a) > (b)? (a) : (b))

Int a = 5, b = 3

MAX (+ + a, b); //a was added twice

MAX (a, b + + + 4); //a was added once
The added result of a may not be expected, but the expected effect of the macro can be achieved by using the template inline function, and the efficiency is similar to that of the macro.
 
template<typename T> 
inline void Max(const T& a,const T& b) 
{ 
f(a>b?a:b); 
} 

Inline function is a compiled mechanism, a bit is look not to come out from the code, but from the difference in execution efficiency of the program, the compiler's handling of the function call is usually similar to an interrupt way, namely when the execution to a function call statement, all current information will be stored in the register, in the code to execute the function, after execution of the register values back, back to the calling function began to form, continue to execute code. After declaring the inline function, the compiler does not compile the function into the calling function but copies the code to where it is called. So the efficiency is higher than the ordinary function, less register and register information steps.
Also note that the inline function is best written to the. H file or directly to the class.
Const allows programmers to specify a semantic constraint that cannot be changed, which the compiler enforces. It means that the value it modifies is constant. Const can externally modify constants in the global or namespace scope of classes, or modify files, functions, or static objects, and Pointers. Notice where the keyword const appears in the "*" pointer, if on the left it means that the value being pointed to is constant, if on the right it means that the pointer itself is constant. A union of the functions of both sides appears. The following points are specifically mentioned here:
(1) cosnt in the iterator
Const STD: : vector< Int> : : iterator iter = vec. The begin (); Iter cannot be changed

STD: : vector< Int> : : const_iterator citer = vec. The begin (); // what iter points to cannot be changed
(2) declaring the return value of the function as a constant not only reduces the unpredictability caused by programmer errors, but also avoids sacrificing security and efficiency. Such as:

Const operater *(const & LHS,const & RHS);
If (a * b = c); // if(a*b==c
If a and b were both built-in types, this code wouldn't make sense, but if it were our custom type, it might make sense, and if we declared the return value to be cosnt, we could prevent it.

(3)const member function, which is to confirm that the member function can act on the const object. And two member functions can be overloaded if they are just constants. The member function is followed by const, which means that the function cannot change the member variable of the class (the code below verifies that the compiler will break an error if it tries to assign a value to its member). The idea is that the compiler thinks of it as a read-only variable. And most const objects are used for reference passing or pointer passing.
 
#include <iostream> 
#include <string> 

class People 
{ 
public: 
People():m_sName(""),m_iAge(0){} 
People(std::string name,int age):m_sName(name),m_iAge(age){} 
void set(int age) 
{ 
this->m_iAge=age; 
} 

void set2(int age) const 
{ 
this->m_iAge=age; 
} 

int get() 
{ 
return this->m_iAge; 
} 
private: 
std::string m_sName; 
int m_iAge; 
}; 

int main(int argc,char **argv) 
{ 
People* p=new People("sky",8); 
p->set(10); 
std::cout<<p->get()<<std::endl; 
p->set2(12); 
std::cout<<p->get()<<std::endl; 
delete p; 
return 0; 
} 


Compiling the file reports the following error message
Const_test.cpp: In member function 'void People::set2(int) const':
Const_test.cpp :16: error: assignment of data-member 'People::m_iAge 'in readonly structure
Const_test.cpp :36:2: warning: no newline at end of file
Cosnt overloading (note: const only matters if the parameter is a reference or pointer). We can try to get rid of the & in the following code, and pass const_int which actually calls the void set(int age) function, to show that const of the parameter is not working. The following is the validation code
 
#include <iostream> 
#include <string> 
class People 
{ 
public: 
People():m_sName(""),m_iAge(0){} 
People(std::string name,int age):m_sName(name),m_iAge(age){} 
void set(const int& age) const 
{ 
std::cout<<"this is const"<<std::endl; 
} 

void test(int& age) 
{ 
std::cout<<"this is non-const"<<std::endl; 
} 

void test(short age) 
{ 
std::cout<<"this is non-const"<<std::endl; 
} 

int get() 
{ 
return this->m_iAge; 
} 
private: 
std::string m_sName; 
int m_iAge; 
}; 

int main(int argc,char **argv) 
{ 
People* p=new People("sky",8); 
const int const_int=12; 
p->test(const_int); 
std::cout<<p->get()<<std::endl; 
delete p; 
} 

(4) the problem of duplication of overloaded function code. From experience, we can conclude that the functions we overloaded by const tend to have a lot of code that is repetitive or even identical. If most of the code is duplicated, we can write the duplicated code as a function and call it separately. If it is the same as the following code, we can call the const function in the non-const function to solve the code duplication.
 
class People 
{ 
public: 
People():m_sName(""),m_iAge(0){} 
People(std::string name,int age):m_sName(name),m_iAge(age){} 
void eat(const People & Person) const 
{ 
std::cout<<"this person info is:{age ="<<Person.m_iAge()<<",name ="<<Person.m_sName()<<std::endl; 
std::cout<<"eating"<<std::endl; 
std::cout<<"end"<<std::endl; 
} 

void eat ( People & Person) 
{ 
std::cout<<"this person info is:{age ="<<Person.m_iAge()<<",name ="<<Person.m_sName()<<std::endl; 
std::cout<<"eating"<<std::endl; 
std::cout<<"end"<<std::endl; 
} 
private: 
std::string m_sName; 
int m_iAge; 
}; 

Then in the non-const eat function, first convert *this type from People& to const People& and let it call the const function, that is, function overload
 
#include <iostream> 
#include <string> 
class People 
{ 
public: 
People():m_sName(""),m_iAge(0){} 
People(std::string name,int age):m_sName(name),m_iAge(age){} 
void eat(const People & Person) const 
{ 
std::cout<<"this person info is:{age ="<<Person.m_iAge<<",name ="<<Person.m_sName<<"}"<<std::endl; 
std::cout<<"eating"<<std::endl; 
std::cout<<"end"<<std::endl; 
} 

void eat(People & Person) 
{ 
static_cast<const People&>(*this).eat(Person); 
} 
private: 
std::string m_sName; 
int m_iAge; 
}; 

int main(int argc,char **argv) 
{ 
People Person("sky",8); 
Person.eat(Person); 
} 

The result of running is

This person info is:{age =8,name =sky
eating
The end

Related articles: