Upload
keshariamit
View
219
Download
0
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_memory8/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.78/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);
}