- The following is a common method for finding an element in an array:
Const int * Find (const int * array, int length, int x) {const int * p = array; for (size_t I = 0; I <length; I ++) {if (* p = x) {return p;} p ++;} return 0 ;}
In this method, we must ensure that the array is int type, know the length of the array, and even determine the existence of such an array. Please use template to override this method to eliminate all these defects.
Refer:
Template <typename T, int n> const T * find (const T * arr, T x) {const T * p = arr; for (size_t I = 0; I <n; I ++) {if (* p = x) {return p;} p ++;} return 0 ;}
I still don't fully understand how to ensure the existence of an array. This solution is just written according to my own understanding. I am very grateful to you for your understanding.
- Suppose there are the following classes:
Class erp {HR * m_hr; FI * m_fi; public: erp () {m_hr = new HR (); m_fi = new FI ();}~ Erp (){}};
If the new FI () constructor fails, how can I detect this problem and release the resources that have been allocated to m_hr?
Refer:
Use the auto_ptr provided in the standard library. auto_ptr is a "pointer_like object", which is also called "smart pointer ", its destructor automatically calls delete for the object to which it points,
In fact, the idea of object-based Resource management Is exactly what C ++ advocates. Objective C ++ tells us that it Is the Initialization time when resources are obtained, that Is, Resource Acquisition Is Initialization.
Class A {HR * m_hr; FI * f_hr; public: A () {auto_ptr <HR> a_mhr (new HR ()); auto_ptr <FI> a_fhr (new FI (); m_hr = a_mhr.release (); f_hr = a_fhr.release (); f_hr = new FI ();}~ A (){}};
- The following classes are available:
# Include <iostream> # include <complex> using namespace std; class Base {public: Base () {cout <"Base-ctor" <endl ;}~ Base () {cout <"Base-dtor" <endl;} virtual void f (int) {cout <"Base: f (int) "<endl;} virtual void f (double) {cout <" Base: f (double) "<endl;} virtual void g (int I = 10) {cout <"Base: g ()" <I <endl ;}}; class Derived: public Base {public: Derived () {cout <"Derived-ctor" <endl ;}~ Derived () {cout <"Derived-dtor" <endl;} void f (complex <double>) {cout <"Derived: f (complex) "<endl;} virtual void g (int I = 20) {cout <" Derived: g () "<I <endl ;}}; void main () {Base B; Derived d; Base * pb = new Derived; cout <sizeof (Base) <endl; // Step 1 cout <sizeof (Derived); // Step 2 pb-> f (1.0); // Step 3 pb-> g (); // Step 4}
What is the output result of the program?
Refer:
In the first step, in the second step, Base and Derived are both classes and reference types, so they are equivalent to the size of a pointer, so they are 4-bit
Step 3, because the parameter in f is 1.0, and the parameter f in Derived is of the complex <double> type, the difference is the same as double, that is, f does not overwrite f in the parent Base, in fact, they are two completely different functions, but the names are the same. Therefore, execute f () in the compliant parent class Base ();
Step 4: execute D: g () because g is a virtual function and the virtual function is dynamically bound. However, because the inherited default parameter value is redefined in Derived, the default parameter value is statically bound, so the value of I is the default value of g () in the Base.
Remember, experience tells us never to redefine the inherited default values.
Program execution result
- Two people take 10 coins in turn, and each time they take 1, 2, and 4 coins, they get the last one to lose and ask if there are any wins
?
Refer:
Each time a person gets a multiple of three.
A. I lost the last person, so I tried to let the other person leave or 5 for me so that I could win the game;
B. Based on a, you can only leave 1, 4, 6, 7, 8, 9
C. if 6 is left for the other party, 2 is left for the other party and 4 is in conflict with B. If 8 is left for the other party, 4 is left for the other party and B is in conflict with B; if 9 is left for the other party, it is also in conflict with B if 2 is left for the other party.
Based on abc, in theory, the first hand is required.
- List the four forced conversions in C ++ and explain the differences?
Static_cast: used to force implicit conversion. It can implement mutual conversion between the built-in basic data types in C ++.
However, const cannot be converted to non-const;
Const_cast: it is usually used to remove the object's constants. Only the four operators can perform such operations;
Dynamic_cast: used for "secure downward transformation", that is, to determine whether an object belongs to a type in the inheritance system.
All the other three types are completed during compilation. dynamic_cast is processed during runtime, and type check is required during runtime. The base class to be converted must have virtual functions.
Reinterpret_cast: performs a low-level transformation.
- The output result of the following code is provided:
# Include <iostream> using namespace std; # define DBL (x) x + xint main () {int a = 3; int B = 4; int c = DBL () * DBL (B); cout <c <endl; return 0 ;}
Answer:
19
The execution result is 3 + 3*4 + 4 = 19.
Some "sub-questions" I worth thinking about