Effective C++(1~4)

1, as the C ++ language to a federal

View C++ as a federation of languages

As we all know, C ++ is a C language evolved. Therefore, C ++ language needs to be compatible C language, and language is a process-oriented language C, compared to other object-oriented language C ++ also inherited defects in C language.
C ++ language, while flawed, but it is still an object-oriented language, object-oriented language by other "incentives", the C ++ language is constantly changing, not the C ++ language C with class of that era. "Effective C ++" the book said, C ++ is a "federal language." Today the powerful C ++ language generally divided into the following sections:

  1. C : block, statements, pre-processing, built-in data types, defects are no templates in C, no overloading, no exceptions.
  2. C ++-Oriented Object : It is part of the appeal C with classes, inheritance, polymorphism, encapsulation, Virutal function (dynamic binding)
  3. C ++ Template : generic programming section, efficient procedure is applicable to a variety of scenarios, various types of program parameters. template function is very powerful, it brings a new programming paradigm, which is the template metaprogramming (TMP template meta-programming).
  4. STL : As a C ++ programmer must have some grasp of the STL, STL has excellent cooperation and coordination of the containers, algorithms, and iterators Statute function object.
  • Efficient Code C ++ programming as the case may need to be considered part of the program corresponding to the written.

2 as far as possible const, enum, inline replacement #define

Prefer consts,enum,and inline to #defines

For the macro, we know, is not a function macro, it simply replaces the expression replacement process may cause problems because of operator precedence unexpected errors, the macro substitution occurs in the preprocessing stage.

# define PI 3.14

Mathematical problems encountered pi, C language we often use macros defined above. Starting this code, we are instead of 3.14 PI calculation, the code will appear in subsequent multiple 3.14. And if we use const define a constant variable, often use variables to calculate redundant data would not exist.

const float PI=3.14;

Members inside the class, we also need to define a const constant argument, # define no scope restrictions, once the macro is defined, he was effective in the subsequent compilation process. #define not only can not be used to define class-specific constants, can not provide encapsulation, const would not have these problems.

class A{
private:
	static const float PI;
};
static const float A::PI=3.14; 

If our class dedicated to maintain a constant need, yes, we need to add static, static members must be initialized outside of the class, this time can be achieved using enum hack to initialize the constants of members in the class.

class A{
private:
	enum{PI=3.14};
};

This situation can not take the address of the enum object will get the address wrong.
In fact, the use of macros also need to pay attention to whether there will be side effects lead to errors. Here it is about the summary of the macro

  • For simple constants, enums preferably in const object or alternatively #define
  • For the shape of a macro function, use is preferably replaced inline function #define

3 possible use const

Use const whenever possible

  1. Often pointer, often variable, constant variables constant pointer
#include<iostream>
int main()
{
	int a = 10;
	const int* p1 = &a;//指向常变量的指针p1,不能通过p1改变a的值,p1可以指向其它地方
	int* const p2 = &a;//常指针p2,只能指向b
	const int* const p3 = &a;//指向常变量的常指针,p3只能指向b,不能通过p3改变b的值
}
  1. const_iteraorGiven const T*type of pointer, you can not const_iteratormodify the content of the element. Statement constant iterator T* constpointer, the iterator can not move (not + or -).
#include<iostream>
#include<string>
using namespace std;
int main()
{
	string str({"I love C plus plus..."});
	const string::iterator it1 = str.end();//it1只能指向str的尾元素位置,不能移动
	string::const_iterator it2 = str.begin();//it2可以指向其它位置,it2具有只读权限
	while (it2 != it1)
	{
		cout << *it2;
		it2++;
	}
	cout << endl;
	return 0;
}
  1. When the function returns a value not want to be assigned, it may be declared as const type. This avoids some of the outside world accidents.
#include<iostream>
using namespace std;

class Rational{
public:
	const Rational operator*(const Rational& r){}
};
int main()
{
	Rational a, b, c;
	//(a*b) = c;这种暴行就会报错
	return 0;
}
  1. Two member functions, if only constants different properties, can be overloaded.
#include<iostream>
#include<string>
using namespace std;

class Text{
public:
	char& operator[](size_t pos)//non-const对象
	{
		return str[pos];
	}
	const char& operator[](size_t pos)const//const对象专属
	{
		return str[pos];
	}
private:
	string str;
};
int main()
{
	Text text;
	const char c1 = text[0];
	char c2 = text[0];
	c2 = text[2];
	return 0;
}
  1. bitwise constness和logical constness
  • bitwise constness also known as physical constness, think the member function only when the object does not change any of the member variables can be said const, that is, one bit will not be changed. const member function can not change any of the non-static member variables within the object. So const member functions can not exist =, otherwise an error.
  • Instances, const member functions, we know that =will not change the contents of the object, we need to be assigned to a variable, give it mutable properties. This time we have followed is logical constness, namely that of logical constants.
  1. non-const version call the const, reduce code redundancy
class Text{
public:
	const char& operator[](size_t pos) const		//const对象专属,不会改变
	{
		return str[pos];
	}
	char& operator[](size_t pos)
	{
		return const_cast<char&>(static_cast<const Text&>(*this)[pos]);
	}
private:
	string str;
};

(static_cast<const Text&>(*this)Converting this into a pointer const type, the call [ ]will const member function call, type const char&, attributes used const_cast removed const.

Why call the non-const member functions do not use const member functions? Const member functions promise that he will not change the contents of the object, but it uses a non-const member functions, if non-const member functions to change the contents of the object, the const member function He made a mistake.

  • The compiler enforces bitwise constness, programming time should use the "constants of the concept."
  • When const and non-const member functions have a substantial equivalents, so that non-const version call the const.

Determining using the object 4 before it has been initialized

Objects that are a initialized Sure make before They're Used
C of Part C ++ (in the STL array) does not guarantee initialization, non-C of C ++ ( STL the vector) will ensure that initialization.
Therefore, in order to avoid errors, the best time to initialize it directly in the object definition.

  1. The compiler initialization sequence is initiated in accordance with the object declaration order. Chestnuts: before you need to initialize the array initialization size.
  2. The constructor is best to all the objects in the initialization list is initialized in declaration order, to prevent the omission. The reason assigned is not within the constructor, the constructor before making body of the function, executes initialization list to initialize, in order to improve efficiency and avoid unnecessary operation.
class First_name{};
class Last_name{};
class  Person
{
public:
	Person()
		:first_()
		, last_()
		, age_(20)
	{}

private:
	First_name first_;
	Last_name last_;
	int age_;
};
  1. For the removal of "cross-compilation unit of the initialization order" problem, replace the non-local objects with local static objects.

static objects within a function is called local static objects, scope of function only in vivo; other static objects called non-local static objects, they will be destroyed at the end of the main function of the time.

When compiling a function of two or more non-local static objects exist unit time, wherein a non-local static object initialization depend on another non-local static objects, because of C ++ definition of "non-local static objects in different compilation units "the relative order of initialization is not clearly defined. Errors may be present, to avoid the wrong way is to use in place of local static non-local static objects, typical examples: Singleton mode.

  • Of built-in objects manually initialized because C ++ does not guarantee initialize them.
  • The constructor is best to use initialization list to initialize declaration order, rather than in the constructor assignment.
  • For the removal of "cross-compilation unit of the initialization order" problem, replace the non-local objects with local static objects.

Guess you like

Origin blog.csdn.net/Vickers_xiaowei/article/details/93408811