C ++ / C ++ 11 usage and keywords

TOC

Some usages:

1. Usage of {}:

struct IdString

{
    std::string name;
    int identifier;
};

IdString var3{"SomeName", 4};
IdString GetString()
{
    return {"SomeName", 4};     //可以直接返回结构体
}

2. New usage of for, usage of auto type:

for (vector ::const_iterator itr = myvec.cbegin(); itr != myvec.cend(); ++itr)
for (auto itr = myvec.cbegin(); itr != myvec.cend(); ++itr)
for (auto &x : myvec.cbegin()) //用auto替换
int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array)
    {x *= 2;}
for (auto &x : my_array)
    {x *= 2;}

This for statement can also be used for C-type arrays, initialization lists, and any type that defines begin () and end () to iterate back and forth.

3. After the return type:

template <typename U, typename V>
auto foo(U u, V v) -> decltype(u*v){
    return u*v;
}
//decltype并不会计算值,只会计算类型

This will clarify the type of u * v

4. Use auto to specify the output type of the template function:

template <typename LHS, typename RHS>
//以下要注意-> decltype(lhs+rhs)这个用法
auto AddingFunc(const LHS &lhs, const RHS &rhs) -> decltype(lhs+rhs)
{
    return lhs + rhs;
}

5. The constructor of a class can be called and initialized by other classes:

class SomeType {
    int number;
    string name;
    SomeType( int i, string& s ) : number(i), name(s){}
public:
    SomeType( ) : SomeType( 0, "invalid" ){}
    SomeType( int i ) : SomeType( i, "guest" ){}
    SomeType( string& s ) : SomeType( 1, s ){ PostInit(); }
};

class BaseClass{
public:
    BaseClass(int iValue);
};

class DerivedClass : public BaseClass{
public:
    using BaseClass::BaseClass; //可以继承基类的构造函数,但是要不就全部继承,要不就一个都不要继承
};

6. Nullptr and NULL:

void foo(char *);
void foo(int);
void foo(nullptr_t);
char* pc = nullptr; // OK
int * pi = nullptr; // OK
int i = nullptr;     // error nullptr不能隐式转换为整数,也不能和整数做比较。
bool b = nullptr;     // OK
foo(pc);             // 调用foo(char *), 而不是 foo(int), 也不是void foo(nullptr_t);
foo(nullptr);         // 调用foo(nullptr_t);

7. Safer enumeration type, you can see the enumeration value hiding:

enum class myEnumeration : unsigned int
{
    Val1,
    Val2,
    Val3 = 100,
    Val4 /* = 101 */,
};

Enum1 :: Val1 meaningful representation and a separate Val1 is whether
this enumeration is type-safe. Enumerated categories cannot be implicitly converted to integers; nor can they be compared with integer values. (The expression Enumeration :: Val4 == 101 will trigger a compile-time error). At this time, a forced conversion is required to compare.

Key words:

1. Inline keywords:

inline is a " keyword for implementation ", not a "keyword for declaration." Generally, the user can read the function declaration, but cannot see the function definition.
The following does not constitute an inline function:

inline void Foo(int x, int y); // inline 仅与函数声明放在一起
void Foo(int x, int y){}

And the inline function is composed as follows:

void Foo(int x, int y);
inline void Foo(int x, int y) // inline 与函数定义体放在一起{}

2. Static keywords:

Some company's coding specifications clearly stipulate that all functions used only in this document must be declared with the static keyword, which is a good coding style.

Global static

If you want multiple files to share variables, but static variables are declared in the header file, the number of times the header file is included, the static variable is created as many times as possible, they are not related to each other.
The distribution of a process in memory is as follows:

  • The .text section holds the program binary file executed by the process
  • The .data section holds all initialized global variables of the process
  • The .bss section holds global variables that have not been initialized by the process (there are a lot of other messy sections in other sections, not shown for now).
    In the entire life cycle of the process, the data in the .data section and .bss section will not be released until the process ends.
    When a process's global variable is declared as static, its Chinese name is static global variable. The storage locations of static global variables and other global variables are no different, they are all in the .data section (initialized) or .bss section (uninitialized), but it is only valid in the source file that defines it. Can't access it. So: if you want to access in other files, don't declare static variables in the header file! ! !
Local static
  • Location: The static local variable is placed in the global storage area .data by the compiler (note: not in the .bss section, for reasons see 3)), so although it is local, it exists throughout the entire life cycle of the program.
  • Access rights: Static local variables can only be accessed by variables or functions within their scope. In other words, although it will exist in the entire life cycle of the program, because it is static, it cannot be accessed by other functions and source files.
  • Value: If the static local variable is not initialized by the user, it will be automatically assigned to 0 by the compiler. There is only one copy. The static local variable read from the global storage area when it is read next time is the value after the last modification. (Multi-threaded attention !!!)
static function

When there are many source files in your program, you will definitely let a source file only provide some interfaces needed by the outside world. Other functions may be written to implement these interfaces. You may not want these other functions. As seen by the outside world (not the source file), these "other functions" can be modified with static at this time.

The scope of the static function is the source file. Think of it as a private function in the object-oriented.

static member variable
  • A static data member is a member of a class. No matter how many objects of a class are defined, there is only one copy of the static data member and it is visible to all objects of that class. In other words, any object can operate on static data members. For non-static data members, each object has its own copy.
  • Static data members do not enter the global namespace of the program, so there is no possibility of conflicts with other global names in the program.
static member function
  • There is no this pointer, so you can only call other static member functions.
  • Non-static member functions can arbitrarily access static member functions and static data members. (Because static is initialized when the program is loaded?)

3、assert:

Should I use assert in the debug phase? The Chinese interpretation of assert is an assertion, for example, "I assert that x must be greater than 0". It is used to eliminate errors, not exceptions.
assert may be turned off by default. In this case, you need to open it with a macro before include:

#undef NDEBUG
#include <assert.h>
//...
aseert(exp);     //exp为0时断言失败,不为0时断言成功,表示正确。
//...

assert () should follow the principle of use, and only one judgment can be tested per assert.

assert(exp1 && exp2 && exp3);
//应该修改为
assert(exp1);
assert(exp2);
assert(exp3);

But in the release version, you should close the assert, because it will cause greater performance loss, you can close the assert before the code test or merge

4、decltype

decltype is the same as the auto keyword and is used for type deduction at compile time

Derivation rules decltype (exp)
  • exp is an expression or variable that is not included in (), then the type of decltype (exp) is the same as exp.
  • exp is a function call, and it is consistent with the function return value type.
  • exp is an lvalue, or is included by (), it is a reference to exp. Assuming the type T, the decltype ((T)) type is & T.
    Lvalue, rvalue
int n = 0, m = 0;
decltype(n + m) c = 0; //n+m 得到一个右值,符合推导规则一,所以推导结果为 int
decltype(n = n + m) d = c; //n=n+m 得到一个左值,符号推导规则三,所以推导结果为 int&
Combined with using / typedef for type definition

It has the same effect as auto, but auto can only be used for static members of the class, not for non-static members of the class (common members). If we want to derive the type of non-static members, we must use decltype at this time.

using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型
using ptrdiff_t = decltype((int*)0 - (int*)0);
using nullptr_t = decltype(nullptr);
vector<int >vec; typedef decltype(vec.begin()) vectype;
for (vectype i = vec.begin; i != vec.end(); i++) { //... }
Reuse anonymous types
//匿名struct
struct
{
    int a;

    int b;

}S;
decltype(S) s;
Combining auto for type deduction
template <typename U, typename V>
auto foo(U u, V v) -> decltype(u*v){
    return u*v;
}




Guess you like

Origin www.cnblogs.com/jerry323/p/12727751.html