Clause 15: Use the priority in the principle as the basis for selection
For more terms, go to source: http://blog.csdn.net/liuchang5
The Chinese often say that "the fish and the bear's paw cannot have both sides", while the English often says that "XX is a double-edged sword ". In essence, this reflects world conflicts, and we must make trade-offs. However, I prefer the Chinese saying that it has a feeling of thinking carefully and thinking twice before a conflict occurs. When you realize that something is indeed a "double-edged sword", conflicts often happen. Of course, some contradictions cannot be avoided. However, if we weigh the pros and cons at the beginning of the design, we may be able to get a lot of inspiration from the design, so as to bypass some traps that will make people drop.
In the previous chapter, you should have learned how to use COM smart pointers and its historical background. The example shows how to write _ com_ptr_t and ccomptr into code. If you are a curious reader, you may secretly say, "Why _ com_ptr_t? But does ccomptr choose to do the same thing ?" I have to say that curiosity is a good teacher, and he also guides us into the terms of this article "Consider the trade-off in Design Principles ".
However, before we begin to discuss this in several summary, we should first set two principles for the smart pointer design:
1. it can properly manage resources. [Intelligence]
2. It is like a pointer. [Pointer]
Yes, these two principles form the big premise of "intelligence" and "Pointer. Almost all our design problems are centered around these two issues. When the solution to the problem is in conflict and cannot be reconciled, we may give priority to its first principle, rather than the second principle. After all, it is more important to ensure that the program is correct without resource leakage or memory errors. We use a case to describe:
Many people should consider whether they can transparently Replace the smart pointer with the original code. In a world without smart pointers, we write code like this:
void SayHello(IFoo *pfoo){ IBar *pbar = 0; if (SUCCEEDED(pfoo->GetBar(&pbar))) { pbar->Hello(); pbar->Release(); } }
Smart pointers bring a lot of convenience. So we replaced the interface pointer with a smart pointer, and the code looked like this:
Void sayhello (ifoo * pfoo) {mysmartpointer <Ibar> * pbar = 0; If (succeeded (pfoo-> getbar (& pbar) {pbar-> Hello (); pbar-> release (); // OH ~ Something went wrong. }}
Yes. At a glance, you will find that the above Code may be used to reference the technology one more time. However, if the project is too old, there will be another 108,000 miles between resource application and release. This concealed error may not be easily discovered.
I have thought of several ways to solve this problem so that intelligent pointers can replace common result pointers transparently. However, after several twists and turns, the final solution can only block such dangerous operations so that no errors will occur (read the article 24 for details ).
You may study more methods to transparently replace smart pointers with your project. The following example may prevent you from continuing:
IView* GetView(int nIndex){ IView* pView = m_Views[nIndex]; pView->AddRef(); return pView;}void UseView(int nIndex){ CComPtr<IView> spView = NULL; spView.Attach(GetView(0)); spView->UserIt();}
In the above Code, an attach operation is required to balance the reference count. The reason is that the value assignment operator of the smart pointer causes the reference count to increase progressively once. The interface pointer does not exist.
What is the root cause? Smart pointers are compatible with the interface pointer counting method. When using smart pointers, they should abide by their specific rules. If you often fall into the trap due to unfamiliar rules, you can review article 5.
So don't think about introducing smart pointers to your old project transparently. Exercise caution when introducing smart pointers. You need to review and modify your code line by line. However, if your project is running normally and you do not need the convenience that smart pointers bring to you urgently. I don't recommend that you do that.
Let's go back to the theme of these terms. The designers of smart pointers should look at these issues in two ways. On the one hand, they should consider different rules for using smart pointers, they also provide several functions and techniques for your code to easily transition to these rules as much as possible.
1. Adjust the reference count using the attach and detach functions.
2. replace-> release and-> addref to block dangerous actions such as direct reference count operations.
3. Provide release () and = NULL to release com resources in advance.
This is the first principle officially observed in these terms: "It can properly complete resource management. [Intelligent] ".
On the other hand, he provides some function overloading so that our smart pointers can be used in a way similar to interface pointers:
1. Reload->, & and other pointer-related operators. This allows the original interface pointer code to be reused.
2. Reload <,! ,! = And so on, so that smart pointers can compare relationships like normal pointers.
3. overload the value assignment operator so that smart pointers can be assigned the same value as interface pointers.
4. Reload the conversion function so that the smart pointer can be implicitly converted to the place where the interface pointer is needed.
This is the second principle that the terms follow: "It is like a pointer. [Pointer] ".
You should understand that smart pointers are only compatible with the reference counting rules of COM at the underlying level, but it is different from the interface pointer usage rules [10] (for the use rules of COM smart pointers, see clause 8 ). This makes it possible for us to introduce intelligent pointers transparently, and makes development and maintenance difficult. It is wise to discard the idea of introducing pointers transparently, so that smart pointers can accomplish resource work as correctly as possible. Because smart pointers are not omnipotent, they also introduce new problems while solving problems.