Points in C++

Embed Size (px)

Citation preview

  • 8/7/2019 Points in C++

    1/31

    The assignment operation also evaluates to the RHS of the assignment operator. The

    expression (a=1) assigns 1 to a and also returns 1. So, the if condition is successful and

    value of a is printed as 1.

    int a=3, b=5, c=1;int x=8;

    x = a < (b < c); The expression (b < c) is evaluated first. It is equivalent to (5 < 1) and

    this expression will return 0. So, the next part of expression will become a < 0 which isequivalent to 3 < 0 and hence result is 0. This result is assigned to x and hence value of x

    becomes 0.

    unsigned int i = 5;while (--i >= 0)

    {

    cout = 0will be always true. Hence, this program goes into an infinite loop. When i becomes 0

    and decremented further, it wraps around and becomes MAXINT.

    Dynamic memory allocation :

    int* ip = new int;

    *ip = i;

    The only function of pre-processor is to expand macros. They can be thought of as

    intelligent text processors. Only compilers have the capability to perform syntaxchecking.

    Function pointers always point to the starting address of a function.

    --------------------------------

    Smart Pointers: Reduce bugs caused by the misuse of pointers while retainingefficiency. Like,

    RAAI capability over raw ptrs.

    Automatic garbage collection

    Bounds checking.a _ptr is not a T *

    disadv: Cant be used with pointers created with new[].

    1. Auto Ptr : Semantics of strict ownership, meaning that the auto_ptr instance isthe sole entity responsible for the object's lifetime. If an auto_ptr is copied, the

    source loses the reference.

    An auto_ptr containing an STL container may be used to prevent furthermodification of the container

    Even when implicitly copying auto_ptr objects -- for instance, if you make a

    function call and pass an auto_ptr object, when the function returns, the contents

    of auto_ptr will be changed to NULL

  • 8/7/2019 Points in C++

    2/31

    // Example 1

    T* pt1 = new T;// right now, we own the allocated object

    // pass ownership to an auto_ptrauto_ptr pt2( pt1 );

    // use the auto_ptr the same way// we'd use a simple pointer

    *pt2 = 12; // same as "*pt1 = 12;"

    pt2->SomeFunc(); // same as "pt1->SomeFunc();"

    // use get() to see the pointer value

    assert( pt1 == pt2.get() );

    // use release() to take back ownershipT* pt3 = pt2.release();

    // delete the object ourselves, since now

    // no auto_ptr owns it any more

    delete pt3;

    } // pt2 doesn't own any pointer, and so won't

    // try to delete it... OK, no double delete

    // Example 2: Using reset()

    //

    void h(){

    auto_ptr pt( new T(1) );

    pt.reset( new T(2) );

    // deletes the first T that was

    // allocated with "new T(1)"

    } // finally, pt goes out of scope and

    // the second T is also deleted

    2. Shared/RCSP: Technique of storing the number of references, pointers, or

    handles to a resource such as an object or block of memory. It is typically used as

    a means of deallocating objects which are no longer referenced.Disadv:

    1. The frequent updates it involves are a source of inefficiency.

    2. Can't handle reference cycles, an object which refers directly or indirectly to

    itself. A mechanism relying purely on reference counts will never consider

  • 8/7/2019 Points in C++

    3/31

    cyclic chains of objects for deletion, since their reference count is guaranteed to

    stay nonzero. Dealt using,

    Weak reference is a reference that does not protect the referent object fromcollection by a garbage collector. An object referenced only by weak references

    is considered unreachable (or "weakly reachable") and so may be collected at

    any time. Weak references are used to avoid keeping in memory referenced butunneeded objects

    Cyclic reference:

    Ex:

    struct CDad;

    struct CChild;

    typedef boost::shared_ptr CDadPtr;

    typedef boost::shared_ptr CChildPtr;

    struct CDad : public CSample{

    CChildPtr myBoy;

    };

    struct CChild : public CSample

    {

    CDadPtr myDad;};

    // a "thing" that holds a smart pointer to another "thing":

    CDadPtr parent(new CDadPtr);CChildPtr child(new CChildPtr);

    // deliberately create a circular reference:

    parent->myBoy = child;

    child->myDad = dad;

    // resetting one ptr...

    child.reset();

    parent still references the CDad object, which itself references the CChild.If we

    now call dad.reset(), we lose all "contact" with the two objects. But this leaves

    http://en.wikipedia.org/wiki/Reference_(computer_science)http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)http://en.wikipedia.org/wiki/Unreachable_memoryhttp://en.wikipedia.org/wiki/Reference_(computer_science)http://en.wikipedia.org/wiki/Garbage_collection_(computer_science)http://en.wikipedia.org/wiki/Unreachable_memory
  • 8/7/2019 Points in C++

    4/31

    both with exactly one reference, and the shared pointers see no reason to delete

    either of them! We have no access to them anymore, but they mutually keep

    themselves "alive". This is a memory leak at best; in the worst case, the objectshold even more critical resources that are not released correctly.

    --------------------------------------------

    Volatile keyword : pushes compiler not to use optimization

    ** Opaque ptr/PIMPL/Chesire Cat/Compiler Firewall:

    Just trhe opaque handle-to-class/struct to,1. enhance encapsulation

    2. reduce compilation dependency/time

    ** COW semantics ex : in string class

    string s("Hello");string t = s; // t and s point to the same buffer of characters

    t+= " there!"; // a new buffer is allocated for t before // appending " there!", so s is unchanged.

    Stack is used for storing local variables as well as for passing parameters. Calling

    function pushes the arguments into stack before control transfers to the called function. In

    addition, return address and values of registers also get pushed on to the stack.

    This is because we cannot assign const * to *.

    Arrays with new cant be initialized. No way to specify initializer.

    Int* ip = new int[12]; -- where ?

    Assume that we have a class MyClass that does not have a default constructor, but whichhas defined a constructor which takes an int as a parameter. This means that the compiler

    is not going to provide a default constructor for the class. When such a condition is true,

    the following statements hold good for MyClass

    1. Every constructor for every class that has a MyClass member must explicitly initialize

    the MyClass member by passing an initial int value to the MyClass constructor.2. The compiler will not synthesize the default constructor for classes that have members

    of type MyClass. If such classes want to provide a default, they must define one

    explicitly, and that constructor must explicitly initialize their MyClass member.

  • 8/7/2019 Points in C++

    5/31

    3. The MyClass type may not be used as the element type for a dynamically allocated

    array.

    4. Statically allocated arrays of type MyClass must provide an explicit initializer for eachelement.

    5. If we have a container such as vector that holds MyClass objects, we cannot use the

    constructor that takes a size without also supplying an element initializer.Hence in our case the program does not compile because of the point 3. above

    Const and Refmembers can be initialized only using the construction initialization list.e.g Sample(int nCount =Because C defaults to external linkage for consts, this makes sense.C++ defaults to internal linkage for constC++ also defines a special rule for initializing conststatic members of an integral

    type. You may initialize such members inside the class body.

    Member Functions default to global linkage.Can be called with object pointer(evenuninit).But this is absurd usage and might crash if,for ex, it accesses a member

    variable.Use Static functions for this.

    Unlike ordinary data members, static members are not initialized through the class

    constructor(s) and instead should be initialized when they are defined.

    Name Hiding: Happens irrespective of same/different method signature in derived class.

    So holds for virtual/static everything.If one name is there in derived it will hide every

    other func of that name in base.

    Functions have class scope by default.But non-static ones need some handle of sortatleast (to be called) that is why static functions are the choice.

    2): m_ciMax(255){

    ..................................

    operator int(){

    cout

  • 8/7/2019 Points in C++

    6/31

    After this this temporary object is used to assign cls2 thereby invoking the overloaded=

    operator. In the cout statement the int() operator is used to extract the integer from cls2

    and then the resulting integer is printed using the cout object.

    ** Deal mixed types by :

    1. Friend func2. conversion func

    ..................

    Provide a overloaded global Public B

    3. If a call omits an argument that has a default value, then the value that is used is

    the one defined by the type through which the function is called, irrespective of the

    object's dynamic type

    This is the reason why static_cast(pb)->SetPublicString() prints In A->Public A

    ** Don't call virtual functions during construction or destruction, because such calls

    will never go to a more derived class than that of the currently executing constructor or

    destructor

    NULL is just a typedef for 0. Hence fn(int) will be called

  • 8/7/2019 Points in C++

    7/31

    ** Temp Objects :

    Avoid techniqs :1. //original expression was : string s= s1+s2+s3;

    string temp=s1+s2;temp+=s3;

    string s=temp;

    2. //original expression was : temp=temp+s3temp+=s3;

    ** Copy Ctor

    Called in 3 cases,1. Object being contructed(initialised) by another object.

    Normally or ctor init list (incase of composition) both2. Pass object by value3. Return object by value

    ** CCtor and overloaded Ass operator :For deep copy,but for objects not object-handles

    class Base {

    public:

    int i;

    int* ip;Base(){}

    Base(const Base& rhs) // const is not mandatory

    {i = rhs.i;

    ip = new int;

    *ip = *(rhs.ip);

    }

    Base& operator =(const Base& rhs) // const is not mandatory

    {

    if(*this = rhs) return *this; // handle self assgnmnt

    i = rhs.i;

    delete ip; // delete previous memory to avoid any leaks

    ip = new int; // assign fresh memory block

    *ip = *(rhs.ip); // fill the value in that blockreturn *this;

    }

    };

  • 8/7/2019 Points in C++

    8/31

    ** placement new

    1. Building a custom-made memory pool or a garbage collector.

    2. For critical applications since its a fail-safe way of allocation since memory is

    pre-allocated.3. When we want allocation on a specific hardware address.

    4. Faster since it takes lesser time in creating object on pre-allocated buffer

    char *pbuff = new char[1024]; // heap allocation using plain newPerson *p = new (pbuff) Person; // placement new uses a pre-allocated

    BufferP -> ~Person(); // Later and explicitly, to free memory

    char pbuff [1024]; //bad idea: stack allocation instead of heapPerson *p = new ( pbuff ) Person; //undefined behavior

    caveats :1. We must ensure that the memory is big enough/valid

    2. We must ensure that the memory is aligned

    3. We must ensure that the memory is deallocated (call dtor explicitly . Even placementdelete is useless here since its for different purpose)

    ** placement delete :

    Placement delete is not supposed to be called directly by the user .Rather, it merelyserves as the deacllocation function that the implementation must invoke when an

    exception occurs during the construction of an object by placement new. To generalize,

    for every version of operator new, C++ provides a matching operator delete. Since there

    are six versions of operator new (ordinary new, placement new, nothrow new, as well astheir array counterparts), there are also six corresponding versions of delete.

    As opposed to a common belief, placement delete does not invoke the destructor of its

    argument; in fact, it has no effect. To ensure that an object constructed by placement newis destructed, you need to call its destructor explicitly.

    ** Ctor Init List:

    1. excp hdling is possibleclass Foo{

    Foo() try : _str( "text of string" ){}catch ( ... ){

    std::cerr

  • 8/7/2019 Points in C++

    9/31

    };

    2. It is important to remember that irrespective of the order of the initialization in theinitialization list, the class members are initialized in the order in which they appear in

    the class, after the base class members are initialized.

    3. Passing params to base classes4. Init const/ref/const static members5. in-situ initlzn of member data too.Optimez than in {} assignmentapproach,for objects not built-in.

    6. Cant access this ptr.7. No error checking possible

    ** Prefer Prefix operator since in the postfix case, the value is increased, but the oldvalue is returned. So one extra temp is created.

    Prefer += instead of +

    7) What is your opinion on the code below?

    class B

    {

    public:B(int x = 0) : mx(x){cout

  • 8/7/2019 Points in C++

    10/31

    the value of 2 has to converted back to a B object. Hence a temporary B object is created

    using the constructor B(int x = 0).

    Subsequently b is assigned to this temporary object using B::operator= "

    **When a class overloads operator new and delete, these have to be static . This isbecause these operators are called before the object is create and after it has been

    destroyed respectively.

    Alternatively it makes sense to think that these operators know how to new and deleteobjects of a given class rather than on a "per object" basis. "

    ** "It is important to remember that if the base class overloads operator new and operator

    delete, the same will be called when creating objects of derived class also. In this case thesizeof(B) is 8. Hence A::operator new is called with size 8 while allocating p. When p is

    destroyed, A::operator delete is called with the size parameter as 4. This is because A has

    not defined it's destructor as virtual. Modify this code and make the destructor as virtual

    and check the program output. Calls to operator new and operator delete for p1 are asexpected."

    ---------What is your opinion on the code below?

    class A{public:virtual A& print(){cout

  • 8/7/2019 Points in C++

    11/31

    }

    a)This code will give compilation error as the overloaded functions differ only in their return typeb)This code will print 532c)This code will print 332d)This code will print 534

    Sorry, the correct answer is b. Remember that the only exceptional case in whichvirtual functions signature can be different in the derived class is if the return type

    of the base class (virtual) function is a public base class of the return type of the

    derived class function. In this case, even if the function signatures are different, they are

    still treated as polymorphic. That is the reason aref.print call is routed to C::print rather

    than A::print. Also note that C::print is private. However since the call to C::print isrouted via the VTABLE the access restriction does not hold good in this case, and the

    private function is called.

    **Virtual inheritance:

    Mechanism whereby a class specifies that it is willing to share the state of its virtual baseclass. Under virtual inheritance, only one, shared base-class subobject is inherited for a

    given virtual base regardless of how many times the class occurs as a virtual base withinthe derivation hierarchy. The shared base-class subobject is called a virtual base class.

    Ordinarily each class initializes only its own direct base class(es). This initializationstrategy fails when applied to a virtual base class. If the normal rules were used, then the

    virtual base might be initialized multiple times. The class would be initialized along each

    inheritance path that contains the virtual base. To solve this duplicate-initialization

    problem, classes that inherit from a class that has a virtual base have special

    handling for initialization. In a virtual derivation, the virtual base is initialized by

    the most derived constructor.Although the virtual base is initialized by the most derived class, any classes that inherit

    immediately or indirectly from the virtual base usually also have to provide their own

    initializers for that base. As long as we can create independent objects of a type derived

    from a virtual base, that class must initialize its virtual base. These initializers are used

    only when we create objects of the intermediate type.

    Another important thing to remember is that virtual base classes are always

    constructed prior to non-virtual base classes regardless of where they appear in the

    inheritance hierarchy.

    Examples of virtual inheritance are plenty in the standard library. istream and

    ostream virtually inherit from ios. iostream multiply inherits from istream and

    ostream.

    class Base {public:

    int i;

    Base(int a) {cout

  • 8/7/2019 Points in C++

    12/31

    i = a;}

    };

    class Der1 : public virtual Base {

    public:

    Der1(int a):Base(a){cout

  • 8/7/2019 Points in C++

    13/31

    ** Templates: On demand, New code for every new type (but just one for one type)

    From the point of view of the compiler, templates are not normal functions or classes.They are compiled on demand, meaning that the code of a template function is not

    compiled until an instantiation with specific template arguments is required. At that

    moment, when an instantiation is required, the compiler generates a function specificallyfor those arguments (argument types to be precise) from the template.

    Thus might lead to code bloat if used indiscriminately.

    Better than macros,for sure.

    Same behaviour for all/diff data types : prefer Templates ex : multiply() for diff types

    Diff behaviour and/or diff data types : prefer Inheritance ex: Shape hierarchy draw()

    Template class can have both templatized and non-templatized member functions.

    Non-type template parameters must be of integral, enumeration, pointer, reference, orpointer to member type, and must be constant at compile time.

    They can be qualified as const or volatile types.Floating point values are not allowed as non-typed template parameters.

    String literals are not allowed.

    Objects of class, struct or union type are not allowed as non-type template parameters,

    although pointers to such objects are allowed.Arrays passed as non-type template parameters are converted into pointers.

    Functions passed as non-type parameters are treated as function pointers.

    Remember that non type parameters of a template are not L-values. They can not

    be modified inside the class. Const

    Note that when friendship is granted to a function template or a class template, it

    becomes the case of unlimited friendship. Friendship is granted to all instantiations of the

    function or class template.

    Static member variables of a class template are shared across all instantiations of a

    given type. This means that objects of type Foo will all share the same static

    member, whereas objects of type Foo will all share the same static

    member, which is different from the static member of type Foo

    ---

    A dependent name is a name that depends on the type or the value of a template

    parameter.Dependent names technically exist outside of template definitions as well, but most

    discussion of dependent names involves the need for disambiguation of dependent names

    within template definitions.

  • 8/7/2019 Points in C++

    14/31

    The compiler binds dependent names when a template is instantiated. The compiler binds

    non-dependent names when a template is defined

    Ex:template class U : A{

    typename T::B x;void f(A& y){*y++;

    }}; // The dependent names in this example are the base class A,

    // the type name T::B, and the variable y.

    --------

    typename keyword:

    rules :

    It appears inside a template Its qualified

    It isnt used in a base class specification or a member initialization list.

    2 uses:

    1. Interchangeable with class keyword in template declaration

    2. To inform compiler that the name used in template declaration is a type name and notan object name. ex: typename X::Name someObject;

    i.e,typename T::iterator * iter;

    since, otherwise this might get parsed as object name and not type name (if there is such a

    object in scope) and lead to compile error,

    class ContainsAType {class iterator { ... }:...

    };

    template void foo() {

    T::iterator * iter;...

    }

    foo(); OK , but what if following class is present

    class ContainsAValue {static int iterator;

    };

    Then, this might be treated as multiplication between static variableiterator and some variable iter !! A compile error ensues.So, better use typename qualifier always.

  • 8/7/2019 Points in C++

    15/31

    export keyword:

    Can precede a in template declaration. It allows other files to use a template declared in adifferent file by specifying only its declaration rather than duplicating its entire

    definition.

    ---------

    Class template specialization :

    The idea of C++ class template specialization is similar to function template

    overloading. This can make the template code for certain data types to be fixed.

    Done if deemed that specific data type class must be written due to,

    1. Data type specific (additional) functionality needs to be given2. Specific data type instantiation (based on the generic template definition) might not

    compile

    3. Partial : you write a template that specializes on one feature but still lets the class user

    choose other features as part of the template.

    1. Full/Explicit template specialization:

    template class mycontainer { , can define additional specific funcs

    here};

    template

    void sort(Array&); Function Template

    2. Partial class template specialization:

    template

    class mycontainer {};ex:// template specialization

    #include

    usingnamespace std;

    // class template:

    template class mycontainer {

    T element;public:

    mycontainer (T arg) {element=arg;}T increase () {return ++element;}

    };

    // class template specialization:

    template class mycontainer { charelement;

  • 8/7/2019 Points in C++

    16/31

    public:

    mycontainer (chararg) {element=arg;} charuppercase ()

    { if((element>='a')&&(element

  • 8/7/2019 Points in C++

    17/31

    template class Stack;

    Alternatively, can have typedef in headers also.Or, exportkeyword.

    -----------------------------------------------------------------------------------

    ** Returning ptr/ reference from a func, problems :

    1. If you have local data in a function, you really ought not return a reference to it at all

    (unless it is static) since it will be be a reference to memory that is no longer valid.

    2. You are returning a reference to member data of an object. Although returning a constreference prevents anyone from changing the data by using it, it means that you have to

    have persistent data to back the reference--it has to actually be a field of the object and

    not temporary data created in the function3. if its ref/ptr to const, then it can be assigned to anything non-const so this wont work :

    (w1 = w2) = w3; // objects

    (w1 = w2) = w3; // ints, since it works so lets not return handle-to-const to keep in// synch with this

    ** What is the output of this program?class MyClass

    {

    int m_nVal;

    public:

    MyClass(int nVal = 0) : m_nVal(nVal){}

    MyClass& operator++(){

    cout

  • 8/7/2019 Points in C++

    18/31

    return ret;

    }

    };

    int main(){

    MyClass cls(0);

    cls++;

    ++cls;

    return 0;

    }

    c) In operator++(int)

    In Copy Constructor

    In operator++()In operator++()

    * EBO (Empty Base Class Optimizn)

    1. composition:

    class Empty {};

    class HoldsAnInt {

    private:

    int x;Empty e; // should require no memory

    };

    But : sizeof(HoldsAnInt) > sizeof(int) !!

    2. Private inheritance

    class HoldsAnInt: private Empty {

    private:

    int x;

    };

    sizeof(HoldsAnInt) = sizeof(int)

    * Use of Private Inheritance:

    1. Impl inheritance

  • 8/7/2019 Points in C++

    19/31

    2. EBO

    3. Need to override some base funcnlty

    * Exceptions/ Special Features in C++:

    1. Privates of base accessible to derived via vtable mechanism.

    2. Co-variant return types

    3. Virtual Inheritance and its init process4. Plain/Static func: class scope, can be called using unassigned class pointer

    Virtual func: object scope,gives run time exception

    5. virtual dTor : otherwise call using base ptr will call base version only,derived versionwont be called thus derived object portion still unallocated thus Memory

    Leak.

    6. Dtor in private : Still objects can be made on heap (not on stack ofcourse),have to

    provide a custom dtor func then, technique used to create heap onlyclass.

    7. CCtor in derived class to handle base class types copy -> POSSIBLE !!

    Ex:class A

    {

    public:A(int n = 0) : mnA(n){}

    A(const A& rhs){mnA = rhs.mnA;}A& operator=(const A& rhs){if(&rhs == this) return *this; mnA = rhs.mnA; return *this; }

    virtual ~A(){}

    protected:

    int mnA;};

    class C: public A

    {public:

    C(int n = 0) : mnC(n), A(n){}

    C(const C& rhs){mnC = rhs.mnC;}

    C& operator=(const C& rhs){if(&rhs == this) return *this; mnC = rhs.mnC; return *this;}

    C& operator=(const A& rhs)

    {if(&rhs == this) return *this; (A&)(*this) = rhs; return *this;}

  • 8/7/2019 Points in C++

    20/31

    void print()

    {cout

  • 8/7/2019 Points in C++

    21/31

    Class B {

    B(int x) {cout calls CCtor not Ass oprtr (obviously)

    12. in Cctor and assnmnt op : not necc to have params as const&

    13. We must return *this in overloaded ass op otherwise normal assigmnt wud work butchain of assignment will/might fail espclly if we return void.

    14. If you do not specify your own set_new_handler() function, new throws an

    exception of type std::bad_alloc.15. Avoid overloading on a pointer and a numerical type.

    16. Avoid data members in the public interface.Since functions are a better/flexibleabstraction.

    ** Absurdities in C++:

    1. Virtual cTor : 1. Trying to call derived version of ctor using existing base ptr toderived object. Non sense !! still wanna do -> factory method pattern.

    2. virtual Static func : since static is class scope and mutually exclusive from virtual funcconcept.3. virtual friend func : But approx would be like :

    An example of where the equivalent of a virtual friend would be useful is if serializing anentire class hierarchy. The trick in doing this is to turn the friend function into a

    lightweight inline proxy function, which forwards the request back to the class. For

    example, consider the simple base class:

    class CPerson

    {

    friend ostream &operator

  • 8/7/2019 Points in C++

    22/31

    // ...

    };

    The friend function forwards the display request back to the CPerson class. Note that we

    pass an instance of CPerson by reference:

    inline ostream &operator

  • 8/7/2019 Points in C++

    23/31

    return ot; }

    1.Prevent instantiation : give a PVF

    2. Stack Only :

    class autoOnly{ public:

    autoOnly(){;}~autoOnly(){;}

    private: void* operator new(size_t)

    { // Dummy Implementation

    }

    void* operator new[](size_t){

    // Dummy Implementation}

    void operator delete(void*){

    // Dummy Implementation}

    void operator delete[](void*){

    //Dummy Implementation}

    };

    3. Heap Only : (caveat : give func for delete, its lets on heap !!!)

    class HeapOnly{public:void DestroyMe() //This function will call destructor{

    deletethis; // Current object will be deleted means destructor}private:

  • 8/7/2019 Points in C++

    24/31

    ~HeapOnly(); // destructor only can be call by member function};

    main(){HeapOnly* h = new HeapOnly(); // fineHeapOnly h; // error !!

    }

    4. Prevent Derivation : 2 approaches

    4.1 make dtor private and give default ctor in derived, but it becomes heapOnly class

    4.2 exploit mix of V-inheritance and 4.1 technique

    class temp{private:

    ~temp() {; } friendclass Final; // Due to friend , Final class can use privatemember functions of temp class};class Final: virtualpublic temp // if not virtual inheritance then

    // still Child can be derived from// Final as a heap only class

    {// Define all data members and functions as you want

    public:

    Final(){;}~Final();

    };

    class Child : public Final{public:

    Child(){ }

    ~Child() { }};

  • 8/7/2019 Points in C++

    25/31

    ** Virtual ctor: (Factory method pattern)

    class Shape {public:

    virtual ~Shape() { } // A virtualdestructor

    virtual void draw() = 0; // A pure virtualfunctionvirtual void move() = 0;

    .. .

    virtual Shape* clone() const = 0; // Uses the copy constructor

    virtual Shape* create() const = 0; // Uses the defaultconstructor};

    class Circle : public Shape {public:

    Circle* clone() const; // Covariant Return Types; see below

    Circle* create() const; // Covariant Return Types; see below ...};

    Circle* Circle::clone() const { return new Circle(*this); }Circle* Circle::create() const { return new Circle(); }

    void userCode(Shape& s){Shape* s2 = s.clone();Shape* s3 = s.create();

    //and for Circle* cp = s.clone(); gives error, need to downcast as //(Circle*) as it still treats return type as Shape* ONLY

    ...

    delete s2; // You need avirtualdestructorheredelete s3;

    }

    ** NCI (Named Ctor Idiom)

    #include // To getsin() andcos()

    class Point {public:

    static Point rectangular(float x, float y); // Rectangular coord's

    static Point polar(float radius, float angle); // Polar coordinates

    // These static methods are the so-called "named constructors"

    private:

    Point(float x, float y); // Rectangular coordinates

    http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/virtual-functions.html#faq-20.7http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/virtual-functions.html#faq-20.7http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/virtual-functions.html#faq-20.7http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/abcs.html#faq-22.4http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/abcs.html#faq-22.4http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/abcs.html#faq-22.4http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/ctors.html#faq-10.4http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/ctors.html#faq-10.4http://f/e-books/FCG%20C++/C++%20FAQ%20Lite/virtual-functions.html#faq-20.7http://f/e-books/FCG%20C++/C++%20FAQ%20Lite/virtual-functions.html#faq-20.7http://f/e-books/FCG%20C++/C++%20FAQ%20Lite/virtual-functions.html#faq-20.7http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/virtual-functions.html#faq-20.7http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/abcs.html#faq-22.4http://d/e-books/FCG%20C++/C++%20FAQ%20Lite/ctors.html#faq-10.4http://f/e-books/FCG%20C++/C++%20FAQ%20Lite/virtual-functions.html#faq-20.7
  • 8/7/2019 Points in C++

    26/31

    float x_, y_;};

    inline Point::Point(float x, float y): x_(x), y_(y) { }

    inline Point Point::rectangular(float x, float y){ return Point(x, y); }

    inline Point Point::polar(float radius, float angle){ return Point(radius*cos(angle), radius*sin(angle)); }

    int main(){

    Point p1 = Point::rectangular(5.7, 1.2); // Obviously rectangular

    Point p2 = Point::polar(5.7, 1.2); // Obviously polar

    ...}

    ** AutoPtr Class

    template

    class auto_ptr {private:

    T* ap; // refers to the actual owned object (if any)

    public:

    typedef T element_type;

    // constructor

    explicit auto_ptr (T* ptr = 0) throw(): ap(ptr) {

    }

    // copy constructors (with implicit conversion)

    // - note: nonconstant parameter

    auto_ptr (auto_ptr& rhs) throw(): ap(rhs.release()) {

    }templateauto_ptr (auto_ptr& rhs) throw()

    : ap(rhs.release()) {

    }

    // assignments (with implicit conversion)

    // - note: nonconstant parameter

  • 8/7/2019 Points in C++

    27/31

    auto_ptr& operator= (auto_ptr& rhs) throw() {

    reset(rhs.release());

    return *this;}

    templateauto_ptr& operator= (auto_ptr& rhs) throw() {

    reset(rhs.release());

    return *this;}

    // destructor

    ~auto_ptr() throw() {delete ap;

    }

    // value accessT* get() const throw() {

    return ap;}

    T& operator*() const throw() {

    return *ap;

    }T* operator->() const throw() {

    return ap;

    }

    // release ownership

    T* release() throw() {T* tmp(ap);

    ap = 0;

    return tmp;}

    // reset value

    void reset (T* ptr=0) throw() {if (ap != ptr) {

    delete ap;

    ap = ptr;}

    }

    /* special conversions with auxiliary type to enable copies and assignments

    */

    auto_ptr(auto_ptr_ref rhs) throw()

    : ap(rhs.yp) {

  • 8/7/2019 Points in C++

    28/31

    }

    auto_ptr& operator= (auto_ptr_ref rhs) throw() { // new

    reset(rhs.yp);return *this;

    }

    template

    operator auto_ptr_ref() throw() {

    return auto_ptr_ref(release());}

    template

    operator auto_ptr() throw() {

    return auto_ptr(release());}

    };

    }

    -------------------------------------------------------------------------------

    ** SharedPtr Class (RCSP)

    class Pointer

    {public:

    //standard construction and destruction:Pointer () {

    cout

  • 8/7/2019 Points in C++

    29/31

    }

    //reference counting related methodsvoid acquire(void){

    ++refCount_;

    } // increase refCount

    unsigned int release(void){

    return(--refCount_);} //decrease refCount

    //accessor

    unsigned int count(void){cout

  • 8/7/2019 Points in C++

    30/31

    ptr_ = rhs.ptr_;

    ptr_->acquire();return(*this);

    }

    }

    ~SmartPointer (void){

    coutcount();

    delete(ptr_);

    ptr_ = NULL;

    }}

    }

    Pointer* operator -> (void) {

    return (ptr_);

    }

    Pointer& operator * () const {

    return(*ptr_);}

    private:Pointer * ptr_;

    }; // SmartPointer

    // client uses SmartPointer as a Stack Variable here

    int main()

    {{

    //sp1 acquires refCount now. so refCount = 1

    SmartPointer sp1 = SmartPointer( new Pointer());sp1->count();

    {

    //sp2 refers sp1 and acquires refCount now. so refCount = 2SmartPointer sp2 = sp1;

    sp1->count();

    } // at this point sp2 relases refCount. so refCount = 1

  • 8/7/2019 Points in C++

    31/31

    sp1->count();

    } // at this point sp1 relases refCount. so refCount = 0 and so here the ptr_ gets deleted

    return(0);

    }