45. Figure out what C + + is written for you behind the scenes, the function called.
If you set an empty class, the C + + compiler declares the following functions: Copy constructors, assignment operators, destructors, a pair of destructors (const and non-const). And if you don't declare any constructors, the compiler will declare a default constructor for you. All of these functions are public.
The compiler-generated default constructors and destructors do not actually do anything, and the resulting destructor is generally non-fictitious, unless a base class with a virtual destructor is inherited. The default fetch address is simply the address of the returned object, which is the return this. While the copy constructor and assignment operators, the non-static data members of the class are "member-based" copies of the construction or assignment, that is, a shallow copy.
When there is a reference in the class, the default copy function can not be implemented, the compiler will error, there are constants, there are pointers, there will be a shallow copy, but there is no error on the run. Classes that contain pointers, references, and const members require themselves to define assignment operators and copy constructors. If you declare an assignment operator or copy constructor in a derived class as private, the compiler will also refuse to generate the corresponding assignment operator and copy constructor for this derived class.
46. Rather compile and link errors, and do not make errors at run time.
When compiled and linked, only a handful of cases cause C + + to throw exceptions, such as memory exhaustion and run-time errors that have little to do with C + +. C + + does not have run-time detection, try to avoid run-time errors.
For run-time errors, there is no error in a run, and it does not mean that it is correct, because each program is running in a different state.
The general way to avoid run-time errors is to make minor changes to the design to eliminate possible run-time errors during compilation. The general design adds new data types to the program to detect the security of the data at compile time.
For a date class, there is a constructor: date (int day,int month,int year); The problem with implementing this class is the legality detection of day and month, which, if not detected, may cause some run-time errors due to its internal logic. An easy way is to use enumerations
Enum Month {Jan = 1,feb = 2,...., Dec = 12};
Instead, the constructor changes to:
Date (int day,month month,int year);
However, this does not have much benefit because the enumeration type is not initialized, that is, the direct Date D (1,month m,2014), can be compiled, but run-time error.
That is, to exempt the runtime check, but also to ensure sufficient security, choose to use a class to implement month.
Class Month{public:static const Month Jan () {return 1;} This is actually called the implicit constructor, in fact the return value is month (1);//....static Const Month DEC () {return 12;} Using a static function, return a constant to prevent arbitrary changes to the int toint () const {return number;} Private:month (int N): Number (n) {}const int number;};
The static member of the calling class returns the corresponding month, and the constructor hides it, preventing the user from creating a new month. But even with such a class, the user can specify an illegal month, as follows:
month* m;data (1, *m, 2014);
Eliminating all run-time detection is impractical. But it will be worth the effort to check that the runtime is moving to compile or link, which will make the program smaller, faster, and more reliable.
47. Ensure that non-local static objects are initialized before they are used.
Be sure to initialize before using the object.
A non-local static object is defined as either a global or a namespace, declared as static in a class, or defined as static within a file scope. Is the value of all objects, the non-static local variables and static variables inside the function.
When a class relies on these non-local static objects, such as having a global object Thecountry in a file, and an object thecity in another file, the initialization of the city is dependent on the initialization of the country. The correct operation of the program depends on the order in which they are initialized. However, it is difficult to determine the correct order of non-local static object initialization, and it is difficult to ensure that each such object is initialized in multiple compilation units, especially if the program becomes more complex by adding more such non-local static objects.
A singleton mode, which transfers each non-local static object to a function, declares it to be static, and second, lets the function return a reference to the object. This allows the user to specify the object with a function called, which is to replace the non-local static object with the static object inside the function. Because when the static object of a function is initialized, C + + explicitly points it out. Another benefit of this is that if the simulated non-local static object is never called, there will never be any overhead for object construction and destruction. A simple example:
Class country{....}; country& thecountry () {Static country tc;//defines and initializes Thecountryreturn tc;//returns its reference. }
48. Attach importance to compiler warnings.
The general programmer ignores the compiler warning, after all, there is no error. To understand the meaning of the various warnings of the compiler. The book is an example:
Class a{public:virtual void F () const{cout<< "FA";}}; Class b:public a{public:virtual void F () {cout<< "FB";};
The book says there's a compiler here that b::f () hides virtual a:::f () error that the F function declared in A is not redefined in B, but is hidden by the new declared non-const f function in B. However, this does not implement polymorphism, and the F function in a is called when an object of B that uses a pointer declared as a points to the F function. But the vs2012 I used did not prompt the warning.
Effective C + + 45-48