Effective use and design of COM smart Pointers-Clause 21: cleverly disguise objects as pointers

Source: Internet
Author: User
Clause 21: cleverly disguise objects as pointers more terms please go to original Article Source: http://blog.csdn.net/liuchang5

Let's discuss how to make my smart pointer look more like a "Pointer" than an "object ". Before that, let's take a look at some features of pointers in C/C ++ so that we can simulate pointer behavior more accurately.

Pointers are an interesting product in C/C ++. Basically, it is a variable. The value range of the integer that a variable can accommodate is generally the maximum address space of a process on a platform. This value stores the address of the specific value object in the process address space. When we use a pointer, we can perform the following operations:

Myobj * p_obj = & m_obj; // a pointer of the myobje type, which contains the m_obj address dosomething (* p_obj); // value operator, returns the specific object p_ninr-> dosomething () to which it points; // uses the pointer operator to access its member dosomethingviaptr (p_obj); // directly transmits the address

The above knowledge seems to be too basic. It seems that such an example can be found in any C/C ++ entry book. The overload of C ++ operators is really a good thing. You can't wait to add the following features:

Template <class T> class cmycomsmartptr {public: // simple. Is the task completed? // Try to find out how many errors can you find? T operator * () {return * P;} operator T * () {return P;} t ** operator & () {return & P ;} T * operator-> () {return P ;}... PRIVATE: T * P ;};

The above code can indeed be executed, but it may cause some inexplicable errors. Try to see it at first? If your insights are not very strong, I have to expose them with the following code:

Myobj * myfuncion () {cmycomsmartptr <myobj> p_obj = & m_obj; (* p_obj). changevalue (); // [1] OH ~ This operation may not change the value of m_obj ~ Const cmycomsmartptr <myobj> p_cobj = & m_cobj; // The m_cobj object has the const modifier p_cobj-> doconstfunc (); // [2]. This statement cannot be compiled, because-> is not a common member. (* P_cobj). doconstfunc (); // return p_obj cannot be compiled similarly; // [3] exceptions may be thrown here, but normal pointers will never .}

Oh ~ It seems that the ugly faces behind this smart pointer have been exposed. Let's summarize his mistakes:

Error [1]: it does not have partition value transfer or reference transfer, but simply returns a t object on the value operator. The program will generate a temporary copy on the stack. Then you make some changes to the temporary object. After this sentence is executed, the temporary object will be destroyed. What about your changes?

Error [2]: This smart pointer does not take into account the support for regular objects (const modified objects ). If a smart pointer is a regular object, it cannot be called to a regular member in a regular object. This is because the-> operator is abnormal.

Error [3]: This smart pointer cannot be compatible with abnormal and secure code. Many of its features do not comply with the C/C ++ conventions. For example, the conversion function should not throw an exception. When it appears in code written for exceptional security, the exceptional security will become invalid.

Once you see these problems, you may be more careful with the compilation of these operators. Refer to several mature solutions, such as ccomptr and _ com_ptr_t. The following smart pointer may be slightly better:

Template <class T> class cmycomsmartptr {public: // version that references the transfer and common constraints considering exceptional security. T & operator * () const // adds the regular constraint and returns a reference {return * P;} operator T * () const throw () // adds the regular constraint, it is not allowed to throw an exception {return P;} t * operator-> () const throw () // compatible with common objects, nor to throw an exception {return P ;}... PRIVATE: T * P ;};

The above improvements are not perfect, but you may have several additional questions. You may be wondering why the operator * () can throw one later? The C ++ standard does not prohibit value-taking operations from throwing an exception. Therefore, considering that the type pointed to by your smart pointer may indeed throw an exception due to the value operation, we have not attached a throw () keyword. Imagine that the T type of the above smart pointer is a _ com_ptr_t, which is indeed ridiculous, but such a program can indeed be executed. _ Com_ptr_t throws an exception during the operator * operation (it throws an exception when it is null), so your smart pointer should also throw the exception, for upper layer processing.

If you are good at observation, you may find another problem. Operator modified with const-> does not return a const Object Pointer !! Yes. This is indeed a problem. So far as the pointer designed in this way does not support the const object, it is better to say that the COM technology does not support the const object. Imagine how a const object can call addref () and release () when necessary (). Therefore, it is always wise to give up the modification of the T type of Const.

Finally, we made him more perfect. But you need to be aware that "exposing errors in the program as early as possible ". Using assertion for program fortification not only makes your smart pointer more robust, but also avoids some usage errors of the caller. When he sees a program crash, he should stop to modify his code and carefully check the logical problems:

Template <class T> class cmycomsmartptr {public: T & operator * () const {assert (P! = NULL); return * P;} operator T * () const throw () // adds a regular constraint and prohibits the throw of an exception {return P;} t * operator-> () const throw () // compatible with common objects, and does not throw an exception {assert (P! = NULL); Return P;}... private: T * P ;};

OK ~ This clause is over.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.