InterviewSolution
This section includes InterviewSolutions, each offering curated multiple-choice questions to sharpen your knowledge and support exam preparation. Choose a topic below to get started.
| 1. |
Write a Message class in C++ containing apis to get and put messages? Ensure that objects of the Message class are destroyed properly in reverse order of creation. |
|
Answer» Deep copy involves using the contents of one object to create ANOTHER INSTANCE of the same class. In a deep copy, the two objects may contain ht same information but the target object will have its own buffers and resources. the destruction of either object will not affect the remaining object. The overloaded assignment operator would create a deep copy of objects. Shallow copy involves copying the contents of one object into another instance of the same class thus creating a mirror image. Owing to straight copying of references and pointers, the two objects will share the same externally contained contents of the other object to be unpredictable. Using a copy constructor we simply copy the data values member by member. This method of copying is called shallow copy. If the object is a simple class, comprised of built in types and no pointers this would be acceptable. This function would USE the values and the objects and its behavior would not be altered with a shallow copy, only the ADDRESSES of pointers that are members are copied and not the value the address is pointing to. The data values of the object would then be inadvertently altered by the function. When the function goes out of scope, the copy of the object with all its data is popped off the stack. If the object has any pointers a deep copy needs to be executed. With the deep copy of an object, memory is allocated for the object in FREE store and the elements pointed to are copied. A deep copy is used for objects that are returned from a function. |
|
| 2. |
How do you implement a Queue in C++ using one or more stacks? |
|
Answer» Stack Unwinding happens during exception handling. During an exception occurrence, the destructor is called to destroy all local objects for the place where the exception was thrown and where it was caught. An exception causes the control to pass on from a try block to the RESPECTIVE exception handler. The destructors for all constructed automatic objects are called at run time which where created since the beginning of the try block. The automatic objects are destroyed in REVERSE order of their construction. Note: The corresponding objects must be created before destruction of the same which takes place during Stack Unwinding. The terminate() function is invoked during Stack Unwinding on a destructor for a unhandled exception. The following EXAMPLE demonstrates this: #INCLUDE <iostream> using namespace std; struct E { const char* MESSAGE; E(const char* arg) : message(arg) { } }; void my_terminate() { cout << "Call to my_terminate" << endl; }; struct A { A() { cout << "In constructor of A" << endl; } ~A() { cout << "In destructor of A" << endl; throw E("Exception thrown in ~A()"); } }; struct B { B() { cout << "In constructor of B" << endl; } ~B() { cout << "In destructor of B" << endl; } }; int main() { set_terminate(my_terminate); try { cout << "In try block" << endl; A a; B b; throw("Exception thrown in try block of main()"); } catch (const char* e) { cout << "Exception: " << e << endl; } catch (...) { cout << "Some exception caught in main()" << endl; } cout << "Resume execution of main()" << endl; }The output of this example: In try block In constructor of A In constructor of B In destructor of B In destructor of A Call to my_terminateIn the try block, two automatic objects are created: a and b. The try block throws an exception of type const char*. The handler catch (const char* e) catches this exception. The C++ run time unwinds the stack, calling the destructors for a and b in reverse order of their construction. The destructor for a throws an exception. Since there is no handler in the program that can handle this exception, the C++ run time calls terminate(). (The function terminate() calls the function specified as the argument to set_terminate(). In this example, terminate() has been specified to call my_terminate().) |
|
| 3. |
What is a Sparse Matrix? How do you implement sparse array using STL map? |
|
Answer» Though both of them PERFORM similar tasks, the differences between a Copy Constructor and an assignment operator is as follows:
|
|
| 4. |
Can constructor be virtual and what about destructor? If yes why and if not why? |
|
Answer» One of the LATEST FEATURES of C++11 are a Move CONSTRUCTOR and a Move Assignment operator. We KNOW that a Copy Constructor and a Copy Assignment is used to make a copy of one object to another, the Move Constructor and Move Assignment is to shift the ownership of the resources from one object to other. This is less expensive that object to object copy. A Move Constructor and Move Assignment operator is not provided by the COMPILER by default and one needs to implement the same. |
|
| 5. |
How do you create a thread? Describe how to pass multiple arguments to the thread? |
|
Answer» The above can be demonstrated using the below program: static INT count=0; class Message { public: void put_message(void); void get_message(void); int message; Message(void) { message=0; COUT<<"Objects Created"<<ENDL; } Message(int k) { message=k; } ~Message() { cout<<"Objects Destroyed"<<endl; } }q; void Message::put_message(void) { message=12345; } void Message::get_message(void) { cout<<"The message is "<<message<<endl; } int main() { Message k(67890); q.put_message(); q.get_message(); k.get_message(); RETURN 0; }Output: Objects Created The message is 12345 The message is 67890 Objects Destroyed Objects Destroyed |
|
| 6. |
What is RTTI and how it can be implemented? |
|
Answer» Below is the logic for the implementation of the above logic In the en-QUEUE operation, the new element is entered at the top of Stack1. In de-queue operation, if Stack2 is empty then all the elements are moved to Stack2 and top of Stack2 is returned. enQueue(q, k): Push the element ‘k’ to Stack1 deQueue(q): While Stack1 is not empty and Stack2 is empty, pop the elements from Stack1 and push to Stack2. The top of the Stack2 popped out is returned. Program to perform the above: #include <iostream> using namespace STD; // implementing the stack class class Stack { int top; public: int a[10]; //Maximum size of Stack Stack() { top = -1; } // declaring all the function void push(int x); int pop(); bool ISEMPTY(); }; // function to insert data into stack void Stack::push(int x) { if(top >= 10) { cout << "Stack OVERFLOW"; } else { a[++top] = x; cout << endl<< "Element Inserted into Stack"<< x ; } } // function to remove data from the top of the stack int Stack::pop() { if(top < 0) { cout << "Stack Underflow \n"; return 0; } else { return (a[top--]); } } // function to check if stack is empty bool Stack::isEmpty() { if(top < 0) { return true; } else { return false; } } // implementing the queue class class Queue { public: Stack S1, S2; //declaring enqueue method void enqueue(int x); //declaring dequeue method int dequeue(); }; // enqueue function void Queue :: enqueue(int x) { S1.push(x); cout << "Element Inserted into Queue "<< x << endl; } // dequeue function int Queue :: dequeue() { int x, y; while(!S1.isEmpty()) { // take an element out of FIRST stack x = S1.pop(); // insert it into the second stack S2.push(x); } // removing the element y = S2.pop(); // moving back the elements to the first stack while(!S2.isEmpty()) { x = S2.pop(); S1.push(x); } return y; } // main function int main() { Queue q; q.enqueue(10); q.enqueue(100); q.enqueue(1000); cout << endl<< "Removing element from queue" << q.dequeue(); return 0; }Output: Element Inserted into Stack10Element Inserted into Queue 10 Element Inserted into Stack100Element Inserted into Queue 100 Element Inserted into Stack1000Element Inserted into Queue 1000 Element Inserted into Stack1000 Element Inserted into Stack100 Element Inserted into Stack10 Element Inserted into Stack100 Element Inserted into Stack1000 Removing element from queue10 |
|
| 7. |
What is upcasting and downcasting? What is object slicing in case of upcasting? |
|
Answer» A Sparse Matrix is an array of elements in which many elements have a value of zero. #include <string.h> #include <iostream> #include <map> #include <utility> using namespace STD; int MAIN() { map<int, string> Employees; // 1) Assignment using array index NOTATION Employees[5234] = "Mike C."; Employees[3374] = "Charlie M."; Employees[1923] = "David D."; Employees[7582] = "John A."; Employees[5328] = "Peter Q."; cout << "Employees[3374]=" << Employees[3374] << endl << endl; cout << "Map size: " << Employees.size() << endl; cout << endl << "Natural Order:" << endl; for( map<int,string>::iterator ii=Employees.begin(); ii!=Employees.end(); ++ii) { cout << (*ii).first << ": " << (*ii).SECOND << endl; } cout << endl << "Reverse Order:" << endl; for( map<int,string>::reverse_iterator ii=Employees.rbegin(); ii!=Employees.rend(); ++ii) { cout << (*ii).first << ": " << (*ii).second << endl; } }Output: Employees[3374]=Charlie M. Map size: 5 Natural Order: 1923: David D. 3374: Charlie M. 5234: Mike C. 5328: Peter Q. 7582: John A. Reverse Order: 7582: John A. 5328: Peter Q. 5234: Mike C. 3374: Charlie M. 1923: David D. |
|
| 8. |
Write a program in C++ to found out whether a word is palindrome or not? |
|
Answer» We cant make a class constructor virtual in C++ to create polymorphic objects. C++ being static typed (the purpose of RTTI is different) language, it is meaningless to the C++ compiler to create an object polymorphically. The compiler must be aware of the class type to create the object. In other words, what type of object to be created is a compile time decision from C++ compiler perspective. If we make constructor virtual, compiler flags an error. In fact except INLINE, no other keyword is allowed in the declaration of constructor. Deleting a derived class object using a pointer to a base class that has a non-virtual destructor results in undefined behavior. To correct this situation, the base class should be defined with a virtual destructor. For example, following program results in undefined behavior. // CPP program WITHOUT virtual destructor // causing undefined behavior #include<iostream> using namespace std; class base { PUBLIC: base() { cout<<"Constructing base \n"; } ~base() { cout<<"Destructing base \n"; } }; class derived: public base { public: derived() { cout<<"Constructing derived \n"; } ~derived() { cout<<"Destructing derived \n"; } }; int MAIN(VOID) { derived *d = new derived(); base *b = d; delete b; getchar(); return 0; } |
|
| 9. |
Write a program to dynamic allocate a 2D Array, assign values to the same, print the values and deallocate the 2D Array. |
|
Answer» Using pthread_create we create a THREAD. We can USE the reference of a structure to pass multiple arguments to the 4th parameter as below: #include <iostream.h> #include <pthread.h> struct arg_struct { int arg1; int arg2; }; void *print_the_arguments(void *arguments) { struct arg_struct *args = (struct arg_struct *)arguments; cout<< args -> arg1<<ENDL; cout<< args -> arg2<<endl; pthread_exit(NULL); RETURN NULL; } int main() { pthread_t some_thread; struct arg_struct args; args.arg1 = 5; args.arg2 = 7; if (pthread_create(&some_thread, NULL, &print_the_arguments, (void *)&args) != 0) { printf("Uh-oh!\n"); return -1; } return pthread_join(some_thread, NULL); /* Wait until thread is finished */ } return pthread_join(some_thread, NULL); /* Wait until thread is finished */ } |
|
| 10. |
2 and 4 (or 4 and 2) as 5 + 5 = 10 |
|
Answer» In C++, RTTI (Run-time type information) is a mechanism that exposes information about an object’s data type at runtime and is available only for the classes which have at least ONE virtual function. It allows the type of an object to be determined during program runtime execution For example, dynamic_cast uses RTTI and following program fails with error “cannot dynamic_cast `b’ (of type `class B*’) to type `class D*’ (source type is not polymorphic) ” because there is no virtual function in the base class B. // CPP program to ILLUSTRATE // Run Time Type Identification #include<iostream> using namespace std; class B { }; class D: public B {}; int main() { B *b = new D; D *d = dynamic_cast<D*>(b); if(d != NULL) COUT<<"works"; else cout<<"cannot cast B* to D*"; getchar(); return 0; } //This is give a run time error: “cannot dynamic_cast 'b' (of type 'class B*') to type 'class D*' (source type is not polymorphic)” //Adding a virtual function to the base class B makes it working. // CPP program to illustrate // Run Time Type Identification #include<iostream> using namespace std; class B { virtual void fun() {} }; class D: public B { }; int main() { B *b = new D; D *d = dynamic_cast<D*>(b); if(d != NULL) cout << "works"; else cout << "cannot cast B* to D*"; getchar(); return 0; } |
|
| 11. |
1 and 5 (or 5 and 1) as 1 + 9 = 10 |
|
Answer» UPCASTING is converting a derived class reference or pointer to a base class. In other WORDS, upcasting allows us to treat a derived type as though it were its base type. It is always allowed for public inheritance, WITHOUT an explicit type cast. This is a result of the is-a relationship between the base and derived classes. Upcasting allows us to treat a derived type as though it were its base type. When a derived class object is passed by value as a base class object, the specific behaviors of a derived class object are sliced off. We're left with a base class object. In other words, if we UPCAST (Upcasting and Down Casting) to an object instead of a pointer or reference, the object is sliced. As a result, all that remains is the sub object that corresponds to the destination type of our cast and which is only a part of the actual derived class. Converting a base-class pointer (reference) to a derived-class pointer (reference) is called downcasting. Downcasting is not allowed without an explicit TYPECAST. The reason for this restriction is that the is-a relationship is not, in most of the cases, symmetric. A derived class could add new data members, and the class member functions that used these data members wouldn't apply to the base class. //Example of upcasting and downcasting: class Parent { public: void sleep() {} }; class Child: public Parent { public: void gotoSchool(){} }; int main( ) { Parent parent; Child child; // upcast - implicit type cast allowed Parent *pParent = &child; // downcast - explicit type case required Child *pChild = (Child *) &parent; pParent -> sleep(); pChild -> gotoSchool(); return 0; } |
|
| 12. |
0 and 3 (or 3 and 0) as 3 + 7 = 10 |
|
Answer» #INCLUDE <string> #include <stdexcept> #include <iostream> using NAMESPACE std; class Palindrome { public: static bool isPalindrome(const std::string& word) { static int i,j; static int count; while(word[count]!='\0') count++; cout<<"count is"<<count<<endl; i=0; j=count-1; while(i<j) { cout<<endl<<"word[i]"<<word[i]<<endl<<"word[j]"<<word[j]<<endl; if(tolower(word[i++])!=tolower(word[j--])) { cout<<endl<<word<<" is not a Palindrome"<<endl; return 0; } } cout<<endl<<word<<" is a palindrome"<<endl; count = i = i= 0; return 1; } }; #ifndef RunTests int main() { std::cout << Palindrome::isPalindrome("Deleveled"); std::cout << Palindrome::isPalindrome("Malayalam"); std::cout << Palindrome::isPalindrome("Bab"); std::cout << Palindrome::isPalindrome("Balam"); } #ENDIF |
|
| 13. |
For example, findTwoSum({ 3, 1, 5, 7, 5, 9 }, 10) should return a std::pair<int, int> containing any of the following pairs of indices: |
|
Answer» #include <iostream> // M x N matrix #DEFINE M 4 #define N 5 // DYNAMICALLY Allocate Memory for 2D ARRAY in C++ int main() { // dynamically allocate memory of size M*N int* A = new int[M * N]; // assign VALUES to allocated memory for (int i = 0; i < M; i++) for (int j = 0; j < N; j++) *(A + i*N + j) = rand() % 100; // print the 2D array for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) std::cout << *(A + i*N + j) << " "; // or (A + i*N)[j]) std::cout << std::endl; } // deallocate memory delete[] A; RETURN 0; } |
|
| 14. |
Write a function that, when passed a list and a target sum, returns, efficiently with respect to time used, two distinct zero-based indices of any two of the numbers, whose sum is equal to the target sum. If there are no two numbers, the function should return (-1, -1). |
|
Answer» #include <stdexcept> #include <iostream> #include <vector> #include <utility> #include <unordered_map> using NAMESPACE std; class TwoSum { public: static pair<INT, int> findTwoSum(const std::vector<int>& list, int sum) { unordered_map<int,int> s; for (size_t i = 0; i < list.size(); ++i) { auto j = s.find(sum - list[i]); if (j != s.end()) return make_pair(i,j->second); s[list[i]] = i; } return make_pair(-1, -1); } }; #ifndef RunTests int main(int ARGC, const CHAR* argv[]) { std::vector<int> list; list.push_back(3); list.push_back(1); list.push_back(5); list.push_back(7); list.push_back(5); list.push_back(9); pair<int, int> INDICES = TwoSum::findTwoSum(list, 12); cout << indices.first << '\n' << indices.second; return 0; } #endif Output is: 3 2 |
|
| 15. |
What is an abstract class and where do we define the same? |
|
Answer» An abstract class is a class which has atleast one pure virtual function. An abstract class cant be instantiated be can be overridden in a derived class as below: //Example below: class Base { public: virtual VOID Get() = 0; virtual bool Get(int i) = 0; virtual int Get(FLOAT x) = 0; virtual ~Base() { } }; class Derived1 : public Base { bool value; public: void Get() { } bool Get(int i) { return i;} int Get(float x) { return (int)x;} }; class Derived2 : public Base { int value; public: void Get() { } bool Get(int i) { return i;} int Get(float x) { return (int)x;} }; int main() { int k=5; int temp = base->Get(k); cout<<"temp is"<<base->Get(k)<<ENDL; return 0; } |
|
| 16. |
What are virtual classes? What is the order of invocation of constructors for them? |
|
Answer» You can make a class VIRTUAL if it is a base class that has been PASSED to more than one derived class, as might happen with multiple inheritance. A base class can't be specified more than once in a derived class: class B { ...}; class D : B, B { ... }; // ILLEGALHowever, a base class can be indirectly passed to the derived class more than once: class X : public B { ... } class Y : public B { ... } class Z : public X, public Y { ... } // OKIn this case, each object of class Z will have two sub-objects of class B. If this causes problems, you can add the keyword "virtual" to a base class specifier. For example, class X : virtual public B { ... } class Y : virtual public B { ... } class Z : public X, public Y { ... }B is now a virtual base class, and class Z has only one sub-object of class B. Constructors for Virtual Base Classes: Constructors for virtual base classes are INVOKED before any non-virtual base classes. If the hierarchy CONTAINS multiple virtual base classes, the virtual base class constructors are invoked in the order in which they were declared. Any non-virtual bases are then constructed before the derived class constructor is CALLED. If a virtual class is derived from a non-virtual base, that non-virtual base will be first, so that the virtual base class can be properly constructed. For example, this code class X : public Y, virtual public Z X one; produces this order: Z(); // virtual base class initialization Y(); // non-virtual base class X(); // derived class |
|
| 17. |
What are the differences between Vector and List in STL? |
|
Answer» Vectors and Lists are defined under C++ Standard Template Library (STL). These data structures are basically sequential containers implemented using STLs. The differences between them are as follows:
|
|
| 18. |
What is a Smart Pointer? Where it is used? What are types of Smart Pointers? Implement a generic Smart Pointer which can be used for all datatypes. |
|
Answer» Smart Pointers are used for better garbage collection so that there are no memory leaks. Using Smart Pointers, there is no NEED to call delete for any memory allocated dynamically and it gets automatically deallocated. Smart Pointers Implementations can be found in C++11 and higher versions. C++11 libraries provide four kinds of Smart pointers namely: auto_ptr, unique_ptr, shared_ptr and weak_ptr. The below example implements a generic smart pointer which can used for all datatypes: #include<iostream> using namespace std; template <class T> class SmartPtr { T *ptr; public: // Constructor explicit SmartPtr(T *p = NULL) { ptr = p; } // Destructor ~SmartPtr() { delete(ptr); } // Overloading dereferncing operator T & operator * () { return *ptr; } // Overloding arrow operator so that members of T can be accessed // LIKE a pointer (useful if T represents a class or STRUCT or // union type) T * operator -> () { return ptr; } }; int main() { SmartPtr<int> ptr(new int()); *ptr = 20; cout << *ptr; return 0; } |
|
| 19. |
What is Singleton Design pattern? Explain with an example how to use Singleton Design pattern to design a class that is Thread safe |
|
Answer» Design Patterns are reusable SOLUTIONS that can be applied to recurring Object Oriented Design problems. Singleton is one such design PATTERN that comes under the category of Creational Design Pattern. It can be used to design such a class which can at most have only single instance at any point of time and cant be instantiated further. This concept can applied for creation of a logger or hardware interface class which can have only one instance running at all times. Example of Singleton class that is thread safe: In order to make the class thread safe, one needs to only create an instance when no other instance exists as below: class Singleton { public: static Singleton* getinstance(); ... private: static Singleton* VOLATILE newinstance; }; Singleton* Singleton::getinstance() { if (newinstance == NULL) { Guarder<LOCK>lock(m_lock); if (newinstance == NULL) { Singleton* volatile temp = static_cast< Singleton* >(operator NEW (sizeof(Singleton))); Newinstance = temp; } } return newinstance; } |
|
| 20. |
Write a program that will convert an integer pointer to an integer and vice-versa. |
|
Answer» The FOLLOWING program demonstrates this. #INCLUDE<IOSTREAM> void main( ) { INT i = 65000 ; int *iptr = reinterpret_cast ( i ) ; cout << endl << iptr ; iptr++ ; cout << endl << iptr ; i = reinterpret_cast ( iptr ) ; cout << endl << i ; i++ ; cout << endl << i ; } |
|
| 21. |
When the constructor of a base class calls a virtual function, why doesn't the override function of the derived class gets called? |
|
Answer» While building an object of a derived class first the constructor of the base class and then the constructor of the derived class gets called. The object is said an immature object at the stage when the constructor of base class is called. This object will be called a matured object after the execution of the constructor of the derived class. Thus, if we call a virtual function when an object is still immature, obviously, the virtual function of the base class WOULD get called. This is illustrated in the following example. #include <iostream> class base { PROTECTED : int i ; public : base ( int ii = 0 ) { i = ii ; show( ) ; } virtual void show( ) { cout << "base's show( )" << endl ; } } ; class derived : public base { private : int j ; public : derived ( int ii, int jj = 0 ) : base ( ii ) { j = jj ; show( ) ; } void show( ) { cout << "derived's show( )" << endl ; } } ; void main( ) { derived dobj ( 20, 5 ) ; }The output of this program would be: base's show( ) derived's show( ) |
|
| 22. |
Write a program that implements a date class containing day, month and year as data members. Implement assignment operator and copy constructor in this class. |
|
Answer» #include<iostream> class date { private : int DAY ; int month ; int year ; public : date ( int d = 0, int m = 0, int y = 0 ) { day = d ; month = m ; year = y ; } // COPY constructor date ( date &d ) { day = d.day ; month = d.month ; year = d.year ; } // an overloaded assignment operator date operator = ( date d ) { day = d.day ; month = d.month ; year = d.year ; RETURN d ; } void display( ) { cout << day << "/" << month << "/" << year ; } } ; void main( ) { date d1 ( 25, 9, 1979 ) ; date d2 = d1 ; date D3 ; d3 = d2 ; d3.display( ) ; } |
|
| 23. |
Write a program that allows to create only one instance of a class? |
|
Answer» This concept is used to create a Singleton Class. Below is CODE snippet demonstrating the same: #include class sample { static sample *PTR ; private: sample( ) { } public: static sample* create( ) { if ( ptr == NULL ) ptr = new sample ; return ptr ; } } ; sample *sample::ptr = NULL ; void main( ) { sample *a = sample::create( ) ; sample *b = sample::create( ) ; }
A static member function CALLED create( ) is used to create an object of the class. In this function the condition is checked WHETHER or not ptr is NULL, if it is then an object is created dynamically and its address collected in ptr is returned. If ptr is not NULL, then the same address is returned. Thus, in main( ) on execution of the first statement one object of sample gets created whereas on execution of second statement, b holds the address of the first object. Thus, whatever number of times you call create( ) function, only one object of sample class will be available. |
|
| 24. |
While overloading a binary operator can we provide default values? Justify your answer. |
|
Answer» No!. This is because even if we provide the DEFAULT arguments to the PARAMETERS of the overloaded operator function we would end up using the binary operator incorrectly. This is explained in the following example: sample operator + ( sample a, sample b = sample (2, 3.5f ) ) { } void main( ) { sample s1, S2, s3 ; s3 = s1 + ; // ERROR } |
|
| 25. |
How do you refer to a name of class or function that is defined within a namespace? |
|
Answer» There are two ways in which we can refer to a name of class or function that is defined within a namespace: Using scope resolution OPERATOR ‘::’ through the using keyword. This is shown in following example: There are two ways in which we can refer to a name of class or function that is defined within a namespace: Using scope resolution operator through the using keyword. This is shown in following example: namespace name1 { class sample1 { // code } ; } namespace name2 { class sample2 { // code } ; } using namespace name2 ; VOID main( ) { name1::sample1 S1 ; sample2 s2 ; } Here, class sample1 is referred using the scope resolution operator.On the other hand we can directly refer to class sample2 because of the statement using namespace name2 ; the using keyword declares all the NAMES in the namespace to be in the current scope. So we can USE the names without any qualifiers. Here, class sample1 is referred using the scope resolution operator. On the other hand we can directly refer to class sample2 because of the statement using namespace name2 ; the using keyword declares all the names in the namespace to be in the current scope. So we can use the names without any qualifiers. |
|
| 26. |
How do I write my own zero-argument manipulator that should work same as hex? |
|
Answer» #include <iostream> ostream& myhex ( ostream &o ) { o.setf ( ios::hex) ; return o ; } INT MAIN( ) { cout << endl << myhex << 2000 ; return 0; } Output: 2000 |
|
| 27. |
How can a '::' operator be used as unary operator? |
|
Answer» The scope resolution operator ‘::’ can be USED to refer to members of the global NAMESPACE. Because the global namespace doesn’t have a name, the notation :: member-name refers to a member of the global namespace. This can be useful for REFERRING to members of global namespace whose NAMES have been hidden by names declared in nested local scope. Unless we SPECIFY to the compiler in which namespace to search for a declaration, the compiler simple searches the current scope, and any scopes in which the current scope is nested, to find the declaration for the name. |
|
| 28. |
Will the inline function be compiled as the inline function always? Justify your answer. |
|
Answer» An inline function is a request and not a COMMAND. Hence it won't be compiled as an inline function always. Inline-expansion could fail if the inline function CONTAINS loops, the address of an inline function is used, or an inline function is CALLED in a COMPLEX expression. The rules for in-lining are compiler dependent. |
|
| 29. |
What are the main characteristics of Static Functions: |
|
Answer» The main characteristics of static functions are as follows:
|
|
| 30. |
What is Name Mangling in C++? Write an example for the same? |
|
Answer» Name mangling is the process through which the C++ compilers give each FUNCTION a in program a unique name. In C++, all programs have at-least a few functions with the same name. Name mangling is a concession to the FACT that LINKER always INSISTS on all function names being unique. In C++, generally programs have at-least a few functions with the same name. Example: In general, member names are made unique by concatenating the name of the member with that of the class given the declaration: class Bar { public: int ival; ... };ival becomes something like: // a possible member name mangling ival__3BarConsider this derivation: class Foo : public Bar { public: int ival; ... }The internal representation of a Foo object is the concatenation of its base and derived class members. // Pseudo C++ code // Internal representation of Foo class Foo { public: int ival__3Bar; int ival__3Foo; ... };Unambiguous ACCESS of either ival members is achieved through name mangling. Member functions, because they can be overloaded, require an extensive mangling to provide each with a unique name. Here the compiler generates the same name for the two overloaded instances(Their argument lists make their instances unique). |
|
| 31. |
Differentiate between a deep copy and a shallow copy? |
|
Answer» Deep copy involves using the contents of one object to create another instance of the same class. In a deep copy, the two objects may CONTAIN ht same INFORMATION but the target object will have its own buffers and resources. the destruction of either object will not affect the remaining object. The overloaded assignment operator would create a deep copy of objects. SHALLOW copy involves copying the contents of one object into another instance of the same class thus creating a mirror image. Owing to straight copying of references and pointers, the two objects will share the same externally contained contents of the other object to be unpredictable. Using a copy constructor we simply copy the data values member by member. This method of copying is called shallow copy. If the object is a simple class, comprised of built in types and no pointers this would be acceptable. This function would use the values and the objects and its behavior would not be altered with a shallow copy, only the addresses of pointers that are members are copied and not the value the address is pointing to. The data values of the object would then be inadvertently altered by the function. When the function goes out of scope, the copy of the object with all its data is popped off the stack. If the object has any pointers a deep copy needs to be executed. With the deep copy of an object, memory is allocated for the object in free store and the elements pointed to are copied. A deep copy is USED for objects that are returned from a function. |
|
| 32. |
What do you mean by Stack unwinding? |
|
Answer» Stack Unwinding happens during exception handling. During an exception occurrence, the destructor is called to DESTROY all local objects for the place where the exception was thrown and where it was caught. An exception causes the CONTROL to pass on from a try block to the respective exception handler. The destructors for all constructed automatic objects are called at run time which where created since the beginning of the try block. The automatic objects are destroyed in reverse order of their construction. Note: The corresponding objects must be created before destruction of the same which takes place during Stack Unwinding. The terminate() function is invoked during Stack Unwinding on a destructor for a UNHANDLED exception. The following example demonstrates this: #include <iostream> using namespace std; STRUCT E { const char* message; E(const char* arg) : message(arg) { } }; void my_terminate() { cout << "Call to my_terminate" << endl; }; struct A { A() { cout << "In constructor of A" << endl; } ~A() { cout << "In destructor of A" << endl; throw E("Exception thrown in ~A()"); } }; struct B { B() { cout << "In constructor of B" << endl; } ~B() { cout << "In destructor of B" << endl; } }; int main() { set_terminate(my_terminate); try { cout << "In try block" << endl; A a; B b; throw("Exception thrown in try block of main()"); } catch (const char* e) { cout << "Exception: " << e << endl; } catch (...) { cout << "Some exception caught in main()" << endl; } cout << "Resume execution of main()" << endl; }The output of this example: In try block In constructor of A In constructor of B In destructor of B In destructor of A Call to my_terminateIn the try block, two automatic objects are created: a and b. The try block throws an exception of type const char*. The handler catch (const char* e) CATCHES this exception. The C++ run time unwinds the stack, calling the destructors for a and b in reverse order of their construction. The destructor for a throws an exception. Since there is no handler in the program that can handle this exception, the C++ run time calls terminate(). (The function terminate() calls the function specified as the argument to set_terminate(). In this example, terminate() has been specified to call my_terminate().) |
|
| 33. |
What is the difference between a Copy Constructor and an Assignment Operator? |
|
Answer» Though both of them perform similar tasks, the DIFFERENCES between a COPY Constructor and an assignment operator is as follows:
|
|
| 34. |
What do you mean by a Move Constructor? |
|
Answer» One of the latest FEATURES of C++11 are a Move Constructor and a Move Assignment operator. We know that a Copy Constructor and a Copy Assignment is USED to make a copy of one object to another, the Move Constructor and Move Assignment is to shift the ownership of the resources from one object to other. This is less EXPENSIVE that object to object copy. A Move Constructor and Move Assignment operator is not provided by the compiler by default and one needs to IMPLEMENT the same. |
|