Notes when using the Bridge Mode
What is the bridge mode? For example, in our USB (Universal Serial Bus), the bridge mode is actually designed. The purpose of the bridge mode is to separate the abstract part from its implementation part so that they can all change independently. That is to say, whether USB flash drives or small fans are inserted. It is only an independent external change, and the computer is not affected. The bridge mode is not used here. Next, let's take a look at a small issue that requires attention when using the bridge mode. Http://blog.csdn.net/yitouhan/article/details/41443221
# Ifndef BRIDGE_H # define BRIDGE_H # include
Class CPU {public: CPU () {m_name = (char *) malloc (32 );};~ CPU () {free (m_name) ;}; private: char * m_name ;}; class Computer {public: Computer (){};~ Computer () {}; CPU & GetCPU1 () {return m_cpu;} CPU * GetCPU2 () {return & m_cpu;} private: CPU m_cpu;}; int main () {Computer computer; {CPU cpu = computer. getCPU1 (); // run error }}{ Computer computer; {CPU * cpu = computer. getCPU2 () ;}} return 0 ;}# endif
When running the above Code, an error should be generated because the first example is incorrect. This involves copying and copying. First, we know that if a copy constructor is not explicitly declared in the class, the compiler will automatically generate a default copy constructor; the default copy constructor is the shortest copy function.
In C ++, when one object is used to initialize another object, only the Members are copied and no resources are copied, the replication method that enables two objects to point to the same resource at the same time is called shortest replication. That is to say, CPU cpu = computer. GetCPU1 (); the cpu and m_cpu m_name in the computer both refer to the same address. Therefore, when the cpu life cycle ends, the cpu calls the destructor. When the computer life cycle ends, m_cpu calls the Destructor again, causing the destructor to be called again, in combination with the above example, m_name will be free twice. Therefore, it may cause a program running error.
Of course, to solve this problem, it is the custom copy constructor (deep copy ).
#ifndef BRIDGE_H#define BRIDGE_H#include
#include
class CPU{ static const int NAME_LENGTH = 32;public: CPU() { m_name = (char *)malloc(NAME_LENGTH); }; ~CPU() { free(m_name); }; CPU(CPU &cpu) { m_name = (char *)malloc(NAME_LENGTH); memcpy(m_name, cpu.GetName(), NAME_LENGTH); } char *GetName(){ return m_name; }private: char *m_name;};class Computer{public: Computer(){}; ~Computer(){}; CPU &GetCPU1(){ return m_cpu; } CPU *GetCPU2(){ return &m_cpu; }private: CPU m_cpu;};int main(){ { Computer computer; { CPU cpu = computer.GetCPU1(); } } { Computer computer; { CPU *cpu = computer.GetCPU2(); } } return 0;}#endif
After such modification, the code runs correctly. However, in practice, the above practices are unscientific.
Obviously, I actually want to obtain the CPU information in the Computer, instead of copying an additional information. The following changes in this direction.
# Ifndef BRIDGE_H # define BRIDGE_H # include
# Include
Class CPU {static const int NAME_LENGTH = 32; public: CPU () {m_name = (char *) malloc (NAME_LENGTH );};~ CPU () {free (m_name) ;}; CPU (CPU & cpu); // {// m_name = (char *) malloc (NAME_LENGTH); // memcpy (m_name, cpu. getName (), NAME_LENGTH); //} // char * GetName () {return m_name;} private: char * m_name;}; class Computer {public: Computer () {};~ Computer () {}; CPU & GetCPU1 () {return m_cpu;} CPU * GetCPU2 () {return & m_cpu;} private: CPU m_cpu;}; int main () {Computer computer; {CPU cpu = computer. getCPU1 (); // compile error} {Computer computer; {CPU * cpu = computer. getCPU2 () ;}} return 0 ;}# endif
This Code only comments a piece of code, and the rest is not modified. However, when compiling this section, the compilation will return errors relentlessly. It is obvious that I only declare the copy constructor and reference it directly without definition. This method can avoid such copy operations (CPU = computer. GetCPU1 ();). This kind of operation is not scientific. When we want to call the CPU function, we can only perform this operation on computer. GetCPU1 (). XXX.
I have not mentioned a line of code from worker, that is, CPU * cpu = computer. GetCPU2 ();. This line of code is correct in three examples and can achieve my goal. However, it is also prone to errors, that is, it is easy to be deleted.
Actually:
CPU & GetCPU1 () {return m_cpu ;}
CPU * GetCPU2 () {return & m_cpu ;}
None of them is absolutely good. You can decide which one to choose based on your own needs! Here we will only talk about the issues you should pay attention to when using them.
Zookeeper