Archive for October, 2008

C++ Tips

C++ Tips

  1. Usage of “const”
    char greeting[]=”Hello”;
    const char *p=greeting; //const data
    char * const p=greeting; //const pointer
    const char* const p=greeting; //const pointer and data
    void fun() const; // Declaration of constant member function
  2. When a derived class of object is deleted through a pointer to a base class with
    a non-virtual destructor, results are undefined. So a class containing any virtual
    function should has a virtual destructor.
    A bad example.
    class base
    //virtual ~base(){};
    class derive:public base
    int *a;
    derive(){a=new int[10];};
    ~derive(){delete [] a;cout<<“deleted”<<endl;};
    int main()
    base *p=new derive();
    delete p;  // ~derive would never be called.
    return 0;
  3. operator=
    class Widget {private: Bitmap *pb;}
    Widget& Widget::operator=(const Widget& rhs)
    delete pb;
    pb=new Bitmap(*rhs.pb);
    return *this;
    Widget obj;
    obj=obj;  //  Oops! runtime error
  4. std::auto_ptr<>;
    void fun()
    std::auto_ptr<myclass> pp(new myclass());

    When fun() exits, the object will be deleted automatically.
    Another better choice is std::tr1::shared_ptr<>
  5. Type cast
    • const_cast<T>():  Remove const property.
      const char str[]=”aaa”;
      char *p=str;  // Can’t compile
      char *p=const_cast<char*>(str);
    • dynamic_cast<T>(): Perform safe downcasting, i.e. casta base class type into derived class type.
      It will check whether the base object is actually a derived object in run time, it not the cast will fail in run time.
      class base{public: virtual void f(){};};
      class derived: public base{public: void print(){puts(“derived”);};};
      int main()
      derived obj;
      base *p=&obj;
      return 0;
      The base class must be polymorphic.
    • reinterpret_cast<T>(): low-level casts.
      pointer –> int
    • static_cast<T>(): force implicit conversions. e.g. non-const object
      to const object, int to double. Perform reverse of many such conversions.
      It can’t assure the correct cast like dynamic_cast<>.
      e.g. void* to typed*, pointer-to-base to pointer-to-derived. It can cast const to non-const.
  6. Pointer to class member function
    double      \\return type
    ( Point::*  \\class name
    pmf )       \\name of pointer
    ();             \\argument list
    pmf can point to a virtual function, and the polymorphism still holds.
  7. class base
    virtual void fun1()=0;
    virtual void fun2()=0;
    void fun3();
    void base::fun3(){};
    void (base::* p1)()=&base::fun1;
    void (base::* p2)()=&base::fun2;
    void (base::* p3)()=&base::fun3;
    What are values of p1,p2, and p3?
    p1=1, p2=5, p3=some memory address. In fact, p1 and p2 are indexes of the virtual table of
    class base, which correspond to virtual two functions.
  8. Difference between reference and pointer.
    Reference should be initialized in its definition.
    The object referenced to by a reference can’t be changed.
    Reference would never be null.
  9. Virtual functions, Overload, Override and Hide.
    class base
    virtual void f(int);
    virtual void f(double);
    virtual void g(int i=10);
    class derived: public base
    void f(complex<double>);
    void g(int i=20);
    int main()
    base b;
    derived d;
    base *pb=new derived;
    b.f(1.0);  \\ base::f(double);
    d.f(1.0);   \\ derived::f(complex<double>)
    \\derived::f is a hide instead of overload.
    \\ Need declaration using base::f(int/double) to call f in base.
    \\ void base::f(double) will lead to override.
    pb->f(1.0);  \\ base::f(double). It is not overridden in derived.
    b.g();        \\ base::g(10).
    d.g();        \\derived::g(20).
    pb->g();    \\ derived::g(10).  Polymorphism.
    delete pb;   \\ ~derived() would never be called. Error!
    return 0;

Read Full Post »