Programming 版 (精华区)

发信人: netiscpu (说不如做), 信区: Programming
标  题: C++ 编程准则与忠告 之 Pointers and References
发信站: 紫 丁 香 (Sun Jul 26 11:22:28 1998), 转信



12 Pointers and References

Back to index 

Rule 42 Do not compare a pointer to NULL or assign NULL to a pointer;
use 0 instead. 


Rec. 48 Pointers to pointers should whenever possible be avoided. 


Rec. 49 Use a typedef to simplify program syntax when declaring
function pointers. 


According to the ANSI-C standard, NULL is defined either as (void*)0
or as 0. If this definition remains in ANSI-C++, problems may arise.
If NULL is defined to have the type void*, it cannot be assigned an
arbitrary pointer without an explicit type conversion. For this
reason, we recommend comparisons with 0 at least until the ANSI-C++
committee has made a decision. 

Pointers to pointers normally ought not be used. Instead, a class
should be declared, which has a member variable of the pointer type.
This improves the readability of the code and encourages data
abstraction. By improving the readability of code, the probability of
failure is reduced. One exception to this rule is represented by
functions which provide interfaces to other languages (such as C).
These are likely to only allow pre-defined data types to be used as
arguments in the interface, in which case pointers to pointers are
needed. Another example is the second argument to the main function,
which must have the type char*[]. 

A function which changes the value of a pointer that is provided as an
argument, should declare the argument as having the type reference to
pointer (e.g. char*&). See Rec. 42! 

typedef is a good way of making code more easily maintainable and
portable. See chapter 18.1, Port.Rec.1. Another reason to use typedef
is that the readability of the code is improved. If pointers to
functions are used, the resulting code can be almost unreadable. By
making a type declaration for the function type, this is avoided. 

Function pointers can be used as ordinary functions; they do not need
to be dereferenced. 



Exception to Rule 42: No exceptions. 



Example 45 Different comparisons of pointers 

  char* sp = new char[100];

  if ( !sp )    cout << "New failed!" << endl;   // No!

  if ( sp == 0 )    cout << "New failed!" << endl;   // Best

  if ( sp == NULL ) cout << "New failed!" << endl;   // ERROR sometimes !!!

        



Example 46 Pointers to pointers are often unnecessary 

  #include 

        

  void print_mij(int** m, int dim1, int dim2)

  {

    for (int i = 0; i&ltdim1; i++)

    {

      for (int j = 0; j&ltdim2; j++ )

        cout << " " << ((int*)m)[i*dim2+j];

      cout << endl;

    }

  }

        

  // Could be written as:

        

  class Int_Matrix 

  { 

    public:

      Int_Matrix(int dim1, int dim2);

      int value(int,int) const;

      int dim1() const;

      int dim2() const;

    // ..

  };

        

  void print_Mij(Int_Matrix m)

  {

    for (int i = 0; i&ltm.dim1(); i++)

    {

      for (int j = 0; j&ltm.dim2(); j++ )

        cout << " " << m.value(i,j);

      cout << endl;

    }

  }

        



Example 47 Complicated declarations 

  // func1 is a function: int -> (function : const char* -> int)

  // i.e. a function having one argument of type int and returning

  // a pointer to a function having one argument of type const char* 

  // and returning an int.

        

  int (*func1(int))(const char*); 

        

  // func1 of the same type as func2

        

  typedef int FTYPE(const char*);

  FTYPE* func2(int);

        

  int (*(*func1p)(int))(const char*) = func2;

        

  // Realistic example from signal.h

        

  void (*signal(int,void (*)(int)))(int);

        



Example 48 Syntax simplification of function pointers using a
typedef 

  #include 

        

  // Ordinary messy way of declaring pointers to functions:

  // double ( *mathFunc ) ( double ) = sqrt;

        

  // With a typedef, life is filled with happiness (chinese proverb):

  typedef double MathFuncType( double );

  MathFuncType* mathFunc = sqrt;

        

  void 

  main()

  {

    // You can invoke the funktion in an easy or complicated way

    double returnValue1 = mathFunc( 23.0 );     // Easy way

    double returnValue2 = ( *mathFunc )( 23.0 ); // No! Correct, but complicated

  }

        


--

                              Enjoy Linux!
                          -----It's FREE!-----

※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: mtlab.hit.edu.cn]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:5.781毫秒