My Profile
Active Members
TodayLast 7 Days
more...
Awards & Gifts
Online Exams
Fresher Jobs
Our fresher job section is exclusively for fresh graduates! Find jobs for freshers in major Indian
cities including Bangalore, Chennai, Hyderabad, Pune or Kochi
Resources
Find educational articles, blogs, discussion threads and other resources.
Colleges
Find details about any college in India or search for courses.
Paid Surveys
|
technical questions
Posted Date: 12 May 2008 Resource Type: Articles/Knowledge Sharing Category: Placement Papers
|
Posted By: sri phani kumari Member Level: Gold Rating: Points: 1
|
|
|
|
3) A static member function does not have a this pointer. Hence referring either implicitly or explicitly to the this pointer within a static member function results in a compile time error. Attempting to access a nonstatic class member refers implicitly to the this pointer and thus results in a compile time error.
4)We cannot intialize class memeber variables in c++, but we can initialize in java
5) all the formal parameters with default values should come at the end itself. we cannot define formal parameters without default values after the formal parameters with the default value.
5) If one or more constructors are declared, then we must also declare the default constructor. compiler will provide default constructor only when no constructors are defined for the class.
6) class Account { private: char *name; double balance; public: Account(const char *temp, double bal = 0.0) { this -> name = temp; this -> balance = bal; } print(); getName(); temp(Account &acct); } // cannot convert const char * to char *;
7) print(cosnt Account &acct) { acct.print(); acct.getName(); //error non-constant function called for constant object Account
8)if we call temp("XYZ") then since temp is expecting reference to Account type, it will temporarily create an object of Account with name set to "XYZ" and balance = 0.0 For temporary conversion, it allways uses single parameter constructor or multiparameter constructor with default values for all but first parameter. we can provide value for only the first parameter.To disallow temporary conversion we can use the keyword EXPLICIT in the definition of the constructor.
10)When we define a vector of 5 class objects as vector acct(5) the intialization of the elements occurs as follows: 1)A temporary object of the underlying class type is created. The default constructor of the class is applied to create it. 2) The copy constructor is applied to each element fo the vector in turn, intializing each class object with a copy of the temporary class object. 3)The temporary class object is destroyed.
11) Difference between initialization and assignment.
12) Always place the initialization of one member with the other in the body of the cosntructor. consider following code: class X { private: int i; int j;
public: X(int val):j(val),i(j) { } }
replace the above with X(int val):i(val) { j = i; }
In case 1, i is not intialized with the value of j intialized to val , but with the value of uninitalized j. This is because the intialization allways takes place in the order in which member variables are defined and not in the order in which member variables are intialized. ie, it will not work in the following way, which we intended to j = val; i = j;
rather it will work in the following way i = j; (j is yet to be assigned the value of val here) j = val; 13) Default value for formal parameters must be specified in the function/constructor declaration or definition only and not at both places.
14) if("Trigyn" == s1) cout< else cout< // bool operator==(String & lhs, String & rhs); it will call constructor String(const char *) and then convert "Trigyn" into the String class object and then compare and before returning from the fucntion it will call destructor for this object.
15)we cannot overload operators both in the class as well as in the namescope.
16) Why does this not invoke the overload operator==(const String& , const String&) "Trigyn" == "Ecapitals"
17)Assignement operators and subscript operators must be allways class member functions. It calls the inbuilt function to check equality b/w to c-type strings.
18) class Derived { public: Derived(Derived &d) { x = d.x; y = d.y; } protected: int x; int y; } we can access protected member x directly through d.x, because every class is a friend of itself.
19)Base class should allways have the default constructor otherwise we cannot create the base class object. if you dont have the default base constructor then you have to memberwise initalize the baseclass subobject, like below: class Base { int i,j;
public:
Base(int ii, int jj) { i = ii; j = jj; } }
class Derived:public Base { int x; int y; public: Derived(int xx, int yy) { x = xx; y = yy; } }
int main() { Base b; Derived d; //This will give error, since to invoke the construcor of derived class first it has create an object of type Base , which it cant do without default constructor. to avoid this redefine the derived class constructor as Derived(int xx, int yy):Base(xx,yy) ie, basically you memberwise intialize the base class object }
20) If member functions in base class and derived class have same name, they do not form overloaded functinos. the member function of derived class will hide the visibility of the member function of the base class. ex: class Base { // constructors void test(String s){}; // // } class Derived:public Base { //constructors void test(int i); // // } int main() { Derived d; d.test(7); // ok calls derived class's test function d.test("Error");//error , expected first argument of type string and not // int. because it tries to call derived class test function and there is no way that a complier can know you are calling the base class test function. All the overloaded candidate functions of a name must all occur in the same scope, if we define two functions with same signature, one in base class and one in derived class we will not get redifinition error because both will be in different scopes. we can solve the above problem by writing this code: class Derived:public Base { void test(int i); void test(string s) { Base::test(s); }
we can also solve the above problem by writing the following code: class Derived:public Base { void test(int i); using Base::test; } The using declaration enters each named member of the base class into the scope of the derived class. The using declaration for a member function cannot specify the parameter list, only the member function name. This means that if the function is overloded within the base class, all the overlaoded instances are added to the scope of the derived class type. we cannot add only one instance of the set of overloaded base class memebers.
21)class Base { virtual void test() { } void print() { } } class Derived:public Base { void test() { } void print() { }
void write() { } virtual void read() { } } int main() { Base *b; Derived d; b = &d; b->test() // calls the test function of derived class. resolved at run time // based on the contents to which b is pointing , late binding. b->print() // calls the print fucntion of the base class only, resolved at compile time only, early binding. b->write() // compile time error, write() function is not a member of base class. b->read() // compile time error, read() function is not member of base class. b->Derived::read(); // Base class has no Derived Class as its base class }
22)class Base { // // private: static int k; // // } The above code will give error - Unresolved external 'Base::k' referenced from E:\BORLAND\C\BASE.OBJ so to compile the above program you should intialize the static variable as int Base::k = 0;
23) If a derived class wishes to access the private members of its base class directly, the base class must declare the derived class explicitly to be a friend. Then the derived base class can access the private members of not only its own base class subobject, but the private and protected members of all the base class objects directly.
24) Friendship is not inherited. The class should grant friendship explicitly and it is never inherited.
25) The derived constructor does not inherit the constructor of its base class. The reasoning is that this could lead too easily to the introduction of uninitialized derived class member errors. For ex, if we subsequently add one or another nonclass data member to the derived class, the inherited base class constructor is no longer adequate for the initialization of the derived class, the programmer addding the new member, however, may not realize this. The error, however, reveals itself not in the construction of the derived object, but in some subsequent use of the object and these sorts of errors prove difficult to trace.
26) A derived class constructor can invoke legally only the constructor of its immediate base class (virtual inheritance provides an exception to this rule)
27) virtual void write(string& s) const; // virtual function virtual void write(string& s) const = 0; // Pure virtual function.
28) virtual function mechanism can only be accessed with the pointers and references. That is we can access the derived class functions through base class pointers or refernces. If we have pointers and references, then late binding technique will be used to call the functions. this allows us to call the functions of the derived class based on the type of derived object. If we use objects to call the functions , then static or early binding takes place and we end up calling the function depending upon the type and not on the actual contents.
29) The default argument to be passed to a function is not determined at run-time, rather, it is determined at compile - time and is based on the type of the object through which the function is being invoked.
30) If you are declaring one or more functions as virtual then it is better to declare the destructor also as virtual.
31) virtually a virtual new operator - page 939 32) overloaded () and -> operator
33) class ZooAnimal { } class Bear:public ZooAnimal { void print(int x); } class Endangered { void print(string y); }
class Panda:public Bear, public Endangered { } int main() { Panda xyz; int 6; xyz.print(6) } // The above statement will result in a compiler error, since there is ambiguity between the two print() statements, even though the parameters are different. The compiler does not know whether to call print function of Endangered class or that of Bear class. The reason for this is the inherited member functions do not form a set of overloaded functions within the derived class. Print() therefore, is resolved only using name resolution on the name print rather than using overload resolution based on the actual argument types passed to print().
34) When we inherit the base class as private, all the protected and public members of the base class are inherited as private members of the derived class. However, if we want to exempt individual members of a base class from the efects of the non public derivation (private), then we have to use the using keyword as below: class Derived:private Base { public: // maintain public access level of the base class using Base::size; protected: // maintain protected access level of the base class using Base::string; } Another reason to exempt individual members is to allow subsequent derivations from this derived class to access the protected members of the private base class.The derived class can only restore the inherited member to its original access level. The access level cannot be made either more or less restrictive than the level originally specified within the base class.
35) In public inheritance all the members of the base class maintain the same access level. In private inheritance the public and protected members of the base class becomes the private members in the derived class.In protected inheritance all the public members and protected members of the base class become protected members of the derived class.
36) virtual inheritance is used to remove the duplication of base class subobjects and the ambiguities to which the duplication gives rise. EX: class ZooAnimal { } class Bear:public ZooAnimal { } class Raccoon:public ZooAnimal { } class panda:public ZooAnimal, public Raccoon { }
now each panda class object consists of two ZooAnimal subobjects, the instance contained within its Bear suboject and the instance within its Raccoon suboject. In terms of simple efficiency, storing two copies of the ZooAnimal suboject wastes storage, because panda needs only one instance. Moreover, the ZooAnimal constructor is invoked twice, once for each subobject. A more serious problem is the ambiguity ot which the two instances give rise, for example, any unqualified access to an ZooAnimal member is a compile - time error, because compiler does not know which instance to call. What If the Bear and Raccoon classes intialize their ZooAnimal subobject slightly differently ? To resolve all these problems we use virtual inheritance.
37) In a nonvirtual derivation, a derived class can initialize explicitly only its immediate base classes. The initalization of a virtual base class becomes the responsibility of the most derived class as determined by the declaration of each particular class object. As an intermediate derived class, direct invocations of all virtual base class constructors are suppressed automatically.
38) Virtual base classes are always constructed prior to nonvirtual base classes regardless of where they appear in the inheritance hierarchy.
39) Under a nonvirtual derivation, each inherited instance is given equal weight in resolving the reference , under a virtual derivation , the inheritance of a virtual base class member is given less weight than a subsequently redefined instance of that member. ex: class ZooAnimal { virtual void onExhibit(); } class Bear: public virtual ZooAnimal { void onExhibit() { } }
class Raccoon:public virtual ZooAnimal { }
class panda:public Bear, public Raccoon { } int main() { panda xyz; xyz . onExhibit(); }
here panda consists of two instances of onExhibit function, one inherited through the Raccon derivation and the other inherited through the Bear derivation.But since Bear has redefined the onExhibit function , the compiler give preference to the Bear::onExhibit function compared to the Raccoon::onExhibit function.If both Raccoon and Bear redefines the onExhibit function the we should explicitly provide the scope resolution operator or it results in ambiguous call to the function.
40) The dyanamic_cast is used for safe casting from a pointer to a base class to a pointer to a derived class, often referred to as safe downcasting.It is used when one must use the features of the derived class that are not present in the base class. Manipulating objects of derived class type with pointers to a base class type is usually handled automatically through virtual functions. In some situations however, the use of virtual functions is not possible. The dynamic_cast offers an alternate mechanism for such situations. ex: class employee { public: virtual int salary(); };
class manager: public employee { public: int salary(); };
class programmer: public employee { public: int salary(); int bonus(); };
void company::payroll(employee *pe) { pe -> salary(); pe -> bonus(); } main() { employee *head; programmer xyz; head = &xyz; company(head); }
The call company(xyz) will give compile time error at company::payroll(employee *pe) function, since bonus is not a member of employee class. That is at compile time the compiler checks for the just type and since pe is object of type of employee, it searches for the bonus function in employee class and hence it will give error. Now if we really want to use bonus function inside the company::payroll and we want to call this function only when the object passed to payroll function parameter is of type programmer, then we have to use the RTTI as below.
void company::payroll(employee *pe) { pe -> salary(); programmer *pm = dynamic_cast< programmer* >(pe); if(pm) { pm -> bonus(); } else { // do something } }
Now at run time, if pe actually points to the programmer object, then the dynamic_cast operation is successfull and pm is intialized to point to a programmer object. Otherwise, the result of the dynamic_cast operations is 0 and pm is intialized to value 0. So we will be calling the bonus function only if the object is of type programmer.The dyanamic_cast actually performs the two operations at once. It verifies that the requested cast is indeed valid, and then only if it is valid does it perform the cast. The verification takes place at run-time. But other c++ cast operations do not verify whether the cast can actually be performed or not.
41 )A dynamic_cast can also be used to convert an lvalue of a base class type to a reference to a derived class type. If a reference dynamic_cast fails, an exception of type bad_cast is thrown.
42) Constructors, Destructors and copy assignment operators are never inherited by the derived class.
43) When the object goes out of the scope, destructor is called automatically. But when the pointer to object goes out of the scope, we have to explicitly call the destructor or we have to delete that pointer(in this case it will first call the destructor based on the type of the pointer and then deletes the pointer itself).
Ex: class Temp { Temp() { // constructor; }
~Temp() { //Destructor; } } void main() { Temp t; Temp *pt;
} Now at the end of the main the destructor for object t is called implicitly(t.~Temp()) If we call explicitly in main, then the object will be destroyed and the compiler will again implicitly call the destructor again and runtime error will occur.But we have to explicitly call the destructor for the object pointed by pt. ie we have to write the following code pt->~Temp() or we have to call delete pt. delete pt will first deletes the object pointed by it and then pt will be deleted. But when the reference to an object goes out of the scope destructors will not be called automatically.... since the references are just alias to some other variable and the destructors will be called only when that variable (to which reference is an alias) goes out of the scope....
44) If we allocate memory in the derived class, we should make the base class destructor virtual.
45) we can use dynamic_cast operator for safe polymorphic run time casts.If we use dynamic_cast operator then atleast one of the classes in the derivation hierarchy should contain a virtual function.
46)If we are using dynamic_cast in our function then we should use -GR option while compiling using "cl". This enables RTTI. If we are using try and catch block in .cpp file then that file should be compiled with -GX option with "cl" compiler. We should use -MD option, to specify to the compiler to use MSVRT.lib files.
47) dynamic_cast(object) dynamic_cast operations are performed at run time. If at run time the object and type are compatible then the cast operation is performed. otherwise it returns null. It is the responsiblity of programmer to check for the return value. But static_cast is perfomred at the compile time only.The type and object should belong to the same hierarchy of derivation.
48) In catch block we can just use the statement throw; to throw back the exception that has been catched.
49) The effect of calling destructors for automatic objects is referred to as stack unwinding;
50) Specifying the types of exceptions that a function may throw a) void f() throw(v1,v2,v3) -- indiacates that f may throw exceptions of type v1,v2 and v3 and exceptions derived from these type only. compile time error will be generated it tries to throw exceptions of other types b) void g(); Function g() may throw any exception c) void h() throw(); Function h() will not throw any exception void e() throw(WClass*); Function e() may throw exceptions of type WClass* or a pointer to a class publicly derived from WClass.
51) unexpected() and terminate() functions are defined in exception.h unexpected() functions calls terminate() function by default which calls abort() function by default. If we want to call some other functions before terminate() function is called by unexpected() function then we have to explicitly specify it as below:
unexpected_handler ueh = address of user function(void (*fun)(void)) set_unexpected(ueh)
similarly if we want to call some other user function before the abort() function is called by the terminate function , we have to explicitly specify it as below: terminate_handler th = address of user function(void (*fun)(void)) set_terminate(th)
void f1() { } void f2() { } unexpected_handler ueh = f1(); set_unexpected(ueh); terminate_handler th = f2(); set_terminate(th);
try { throw expection; } catch(...) { unexpected(); }
When the expection is thrown in the try block, the unexpected function will first call the user function f1 and then it calls the terminate function. The terminate function will first call the user function f2 and then it will call abort. set_unexpected will return the last
52) A friend specifier cannot appear outside the class definition. Thus a programmer who does not have access to the source code for the class cannot grant friendhip to a function.Hence the integrity of the class is still preserved.
53) A function defined within the declaration of a class is inline by default.
54) delete operator must not be applied to memory not allocated on the free storage(ie. memory allocated using new operator)
55)If we want to prevent assignments we should declare the copy constructor and copy assignment functions as private and omit defining them.
56) When ever we have pointer variables as member objects, then we should allways provide copy constructor and assignment operator without fail..
57)We should not call a constructor within constructor..Ex: If a constructor of class X calls another constructor of class X, the compiler actually initializes a temporary local object of class X. It does not use the call to initialize the this object. Instead of calling a constructor inside another constructor the common code can be shared in some member functions.
58)example to function call which can apprear on left side of an assignment operator is the overloaded subscript operator..
class Array { float& operator[](int i);
private: float data_[100];
float& Array::operator[](unsigned i) { return data_[i]; }
main() { Array a; for(int i = 0; i < 100; i++) { a[i] = i; } }
59) Static data members can be private, protected or public but global variables are always public... static data members are of class scope whereas global variables are of file scope...
60) static member functions is similar to friend function in that neither has an implicit 'this' parameter and both have access to the class's private and protected variables and functions..
1) We cant initialize data members within a class at the time of their declaration because no memory we will be allocated at the time of class declaration. Memory will be allocated only when the objects are created. Const member can be intialized by using member intialization technique.
2) The disadvantages of the virtual functions are run time overhead since with virtual functions, the compiler will not use early binding technique. At run time based on the actual object, the corresponding virtual function will be called. 3) A pointer to base class can contain objects of its own type or objects of its derived class type. So if desturctors are not defined as virtual, then if we call the destructor with the pointer to base class, compiler will use early binding technique and it will always call the base class destructor. Even when the base class pointer is pointing to the derived class object, only base class destructor will be called. So to call suitable destructor based on the actual object rather than the type of the variable, we have to declare the base class destructor as virtual.
4)It is not possible to invoke a pure virtual function, since if a class defines a function as pure virtual function, then that class becomes abstract class and we cannot instantiate the abstract class. So without an object we cannot invoke the pure virtual function or any other function. Even the derived class inherits the virtual function and if the derived class does not provide any definition for that function, then it will remain as pure virtual function in derived class also, which makes the derived class an abstract class.
5) The virtual functions binding is static, when the virtual function is invoked through the object type and not with the pointer to object type. Also the virtual function bindint is static, when we invoke it will class scope operator or when the virtual function is invoked in the base class constructor or destructor.
6) Virtual functions are called based on the actual object at the run time. But to create an object, the constructor should know all the details about the object it is going to construct. So constructors cannot be defined as virtual.
7) When a class inherits one or more classes which in turn have same base class then by virtue of inheritence the most derived class will be having more than one subobject of the super base class and if the immediate base classes initialize these super base class in different ways, then it leads to ambiguity in the most derived class and even if they are initialized in the same way, it leads to unnecessary wastage of memory.With the virtual base class technique the most derived class is given the responsibility of invoking the constructor of the base class defined as virtual which results in creating only one subobject of the indirect base class. ex: class A: {}
class B:public class A {}
class C:public class A {}
class D:public class B, public class A {}
Now since class A is not defined as virtual, when we create an object of class D, the immediate base class subobjects B and C will be created. The subobjects B and C will each inturn create subobjects of class A and hence finally object of class D will contain one subobject of B, one subobject of C and two subobjects of class A. If we define class A as virtual, then since now class B and Class C becomes intermediate classes in the derivation hierarchy, while creating the object of class D, class B and Class C constructors will not create class A subobject, but the functionality of creating the class A subobject is given to class D constructor and hence the class D contains only one subobject of type class A instead of two.
9) We cannot create a reference to void, reference must allways refer to an object.
10) The nonstatic member function calls can be concatenated together using the pointer this. ex: class A { int getSum(){}
A& Add() { //----- return *this; } }
main() { A* a = new A(); a -> Add() . getSum(); }
Now the operators -> and . are left associative, ie they are called from left to right. so first a -> Add will be executed and then to call getSum(), it needs pointer to class type A. So Add method should return *this. Hence with the use of pointer this we can concatenate the nonstatic member functions.
11) COUT is preferred over printf, because with COUT , there is no need to explicitly specify the type of the variable which we are printing, ie, there is no need to specify %s, %d .... with cout.
12) malloc() allways returns the void * and it is the programmer responsibility to to cast it back to suitable type. If malloc fails to allocate memory it will return null and hence programmer has to use if loop to check whether malloc has allocated memory or not. New allways returns the suitable pointer type based on the type of data to be stored. It throws bad_cast exception if it fails and also new can be overloaded.
13)Static members belongs to class. If we want a member variable to be shared across all the objects of its type, then we use static members. static members can be used to share information among all the objects of a particular class type and objects of its derived class type or they can be use to keep track of number of objects created.
14) const functions are not allowed to modify the member variables. Hence the programmer cannot accidently modify the variables in const functions. So we can mark read-only functions as const functions. Also for const objects we can call only the const functions, since the state of the const objects cannot be changed, the const object can rely only on const functions. 15) inline specifier will result in default internal linkage.
16) The derived class can access the public members of the base class. If we define the base class member variables as private the the derived class cannot access those members directly and we have to give public interface (get methods) to access those variables. Making them public will give access not only to derived class but also to external program. So if we want to give direct access of base class members to derived class , but not to other classes,then we have to declare them protected. If the derived class wants to make the base class subObject public member variables as protected, then it has to use the protected accessor while deriving.
17) There is no need for the derived class to declare a default constructor, it the base class provides one. But if the derived class declares one or more constructor of its own then the derived class should also define one default constructor. Even if the derived class does not define any constructors, then while creating the derived class object, the compiler uses the default base class constructor to create the base class sub object.
18) The static member functions are not called with the 'this' pointer and hence the static member functions do not have access to the 'this' pointer as opposed to the non-static member functions which are implicitly called with the 'this' pointer. So since static member functions do not have access to the this pointer, non-static members cannot be called within the static member functions. But since static members are shared across all the objects, non-static member functions can acess static member of its class.
19) If we specify the default arguments in arbitarary manner in the functions argument list, then there is no way for compiler to know the programmer intention. It cannot identify the variables for which the programmer intends to use default arguments and for which to use the programmer supplied values.
20) scope resolution operators are used to access the global variables, which otherwise will be overridden by the local variables with the same name and scope resolution operators are also used to remove any ambiguity while accessing the member variables or member functions which have same precedence levels. This occurs in situations of multiple inheritance.
21) Although the reference serves as a kind of a pointer, we cannot initialize it to the address of an object. Once defined a reference cannot be made to refer to another object, but pointer canbe made to point to other objects.Reference must allways refer to an object but we can define a pointer that does not point to any object. Assignment of one reference with another changes the object being referenced and not the reference itself but assignment of one pointer with other pointer will change the pointer itself, but not the value at that pointer.
Ex: int i1 = 50; int i2 = 100; int &r1 = i1; int &r2 = i2; int *p1 = &i1; int *p2 = &i2;
r1 = r2 The above code will not make r1 to refer to i2, to which r2 is referring, but actually it sets the value of i1, to which r1 refers to 100(i2); Now if we write p1 = p2, then the values of variables i1 and i2 will not be changed, but p1 and p2 will both be pointing to the variable i2.
22) The function parameters are passed by value. If the function parameters passed to the class are very big, then an expensive extra copy has to be made. Instead we pass function parameters as references, then only address are passed. Also with references we can avoid the syntax difficulties, usually associated with pointer variables.
23) To allocate an array of instances from the free store, we should declare a default construtor in the class definition or we should not define any constructors in the class definition itself.
24) Member intialization list can be use to initialize the const and reference variables. The member intialization list should be used to intialize the member class objects. If we intialize the member class objects within the body of constructor, then it will first call the default constructor for that object and then it will call the copy assingment function .If we use member intialization list then it will directly use the copy constructor to intialize that object.
26) If a function is defined as inline then its code gets expanded at the point of its call during its compilation. If it does not defined as inline, then at run time the program controler will have to save the current instruction pointer and the current environment pointer in some temporary variable and then it has to load the new environment pointer and instruction pointer to call the code of the function. When the function call returns it has to retrieve the saved pointers to continue its execution. All this adds to the runtime overhead. Virtual functions cannot be inlined since the virtual functions are called at the run time based on the actual contents and not on the type.
27) If no handler is specified to catch the exception being thrown, then when the exception condition occurs, then the program controller calls the terminate() functions, which abnormaly terminates the program.
28) If the handler of the exception cannot deal with the exception, then will re-throw the exception with the assumption that the caller of the function is better equipped to handle such exceptions.
29)Instructions will be stored in the stack and the program controller will pop one instruction at a time from the top of the stack and after executing it, next instruction will be poped from the stack. Unwinding the stack means, poping the instructions from the stack without actually executing it.
30) We cannot overload a destructor, since the name of the destructor should be same as the name of the class and since the destructor does not take any parameters, there is not way to overload the destructor.
31) The reference to class object is just an alias to the existing class object and once the class object goes out of the scope, destructor for that object will be called and the memory will be free. So the memory to which the reference variable will be pointing will be freed and hence there is no need to call the destructor when the reference to a class object goes out of scope. 32) To allocate an array of instances of a class, the class should not define any constructors or it should define default constructor or a constructor which has default values for all arguments.
33)Template instantiation happens at run-time.
1) Can a copy constructor take more than one argument
2)Can a copy constructor take a parameter by value instead of reference
3) In a copy constructor, can you pass the existing instance into the function by value
4)class Temp { Temp(){}; //Default constructor Temp(const Temp& rhs){}; //copy construtor }
void main() { Temp t1 = *new Temp(); }
Which constructor will be called -- default or copy ?
5) How do you make sure that no instances of base class is created and only derived classes can generate its instance
1) A copy constructor may take additional arguments, provided that they have default values.
2)No..Compiler will not allow you to do that.
3) It will result in infinite loop and finally stack overflow
4)Both Default / copy will be called
5) Make the desturctor of the base class protected.
Single constructor problem ------------------------------------- #include #include
class Temp1 { public: Temp1(char* name="DEFAULT") { }
Temp1(int i = 0) { } };
class String { public: String(const Temp1& t1="Default", int len = 0) {
} };
int main() { printf("Hello, world\n"); String s1("See Naples and die.",13); String s2(169); String s3; s1;s2;s3;
return 0; }
References: -------------------------- 1) int& const rInt = Val and int& rInt = Val are both equivalent...snce a reference once intialized cannot be aliased to refer another object -- it implies that a reference is in fact a constant reference.
2) A reference my not be initialized with an rvalue and with incompatible type...But if the reference is to a const object it may be initialized with an rvalue or incompatible object Ex: int& r1 = 13; //error const int& r2 = 13; //o.k.
3) A reference to void is not permitted
4) There can be no reference to references, no references to bit-fields, no array of references and no pointers to references.
5) A function that returns a reference type cannot return a local variable.
6) References to class member functions may not be declared
Operator Overloading:
1. When an overloaded operator is a class member, the class member operator is only invoked when the operator is used with a left operand that is an object of class type.If the operaotr must be used with a left operand of another type, then the overloaded operator must be a namespace member.
2. The assignment(=), subscript([]),call( () ) and member access arrow( -> ) operators should be allways defined as a class member operators. Defining them as a namespace member is flagged at compile time as an error.
3. The following 4 c++ operators cannot be overloaded.... 1) :: 2) * 3) ? 4):
4. Predefined meaning of an operaotr for the built-in types can not be changed.ex: int operator+(int,int) is an error.
5. Operator new() and operator delete() are static members of their class and they obey the usual constraints for static member functions.These operators are made static member functions withut the need for the programmer to declare them static explicitly..
6. A class member operator new() must have a return type of void* and take a first parameter of type size_t..size_t is defined in the systme header file ..
7.The class member operator delete() must have a void return type and a first parameter of type void*..
8. To create an array of objects you should allways provide a default constructor..otherwise the new XYZ[ ] expression will be an error, if XYZ class defines some constructors and does not provide default constructor..
9. A Conversion function takes the general form operator type(); A Conversion functions in which type represents either an array or a function type are not allowed..A Conversion function must be a member function.Its declaration must not specify a return type nor can a parameter list be specified...
1) Operator =() is not inherited by the derived classes bcs the instance of the operator=() is automatically constructed for each class.
2) Static members of a base class is shared among all the derived classes.
3) To allocate an array of instances of classes from the FREE STORE, it must either not define any constructor or define a constructor that does not require any arguments.
4)A private class is one with no public constructor. A derived class may not instantiate a private class.
5) how does a destructor enforce information hiding -- by declaring desturctor as protected or private.
6) The member initialization list is also useful when the names of the arguments of the constructors are same as that of members of the class.
7)To declare an Array of constant data members -- Declare the array a non-const in one class and then use a const object of this class as data member in another class.
8)Overloaded Operator functions may not have default argument values ex: char& operator[](int Which = 0); //error
9)The definition of "+" does not support the equivalent compound assignment operator ("+=").
10). and .* and :: and ?: and sizeOf and typeid along with 4 cast operators cannot be overloaded
11) only function call operator function -- operator()() may take more than one explicit argument. Only when an argument is overloaded as friend, two arguments can be specified..
12)If the operator is overloaded as both the friend function and the member function, then the compiler will call the member operator function. The friend operator function must be invoked explicitly as: operator+(str1,str2)
13)Operator[] function must be member of the class
15)The operator() must be a non-static member function
16)By declaring the copy functions as private we can disallow the copying of instances.
17)If the function operator ->() is defined for the class X, the expression x->m is resolved as (x.operator->())->m.. so the function operator ->() must either return a pointer to a class object or return an object of a class for which operator-> is defined. Here x should be either class object or a reference to a class object. If x happens to be a pointer to class object of type X, then the compiler cannot distinguish b/w the predefined and overloaded instance.in such case we have to explicitly invoke the operator->() function. operaotr->() cannot be a static function also.
18)the overloaded version of new should return a void* and must have a size_t as its first argument.
19)class specific new and delete operator functions are always static even if they are not explicitly declared to be so.Hence ehy may only access to other static members of the class and thus, they cannot be virtual functions.
1) Static members are inherited from the base class, but only one copy is maintained between the base class and the derived class.
2) To allow the derived class to access the base class members and at the same time hiding it from other classes, we need access specifier protected.
3)We cannot declare a derived class whose size is less than that of its base class. The size of the derived class should be atleast as much as that of the base Class. The size of the empty class is 8.
4) we cannot access members of a derived class from within its base class.
5) If the derived class itself declares the member variables then we have to provide the default constructor.If the derived class does not define any constructor then compiler will implicitly provide default constructor, but if the derived class defines one or more constructor then it is mandatory to provide one default constructor.
6) If the base class does not contain any member variables, then there is no need to provide default cosntrutor.IF the base class contains one or more constructor then it is necessary to provide the default constructor then it is necessary to provide the default constructor. Otherwise you have to memberwise intialize the base class subobject using one of the constructor provided by the base class.
7)The overloaded assignment operator need not be redefined in the derived class of base.The compiler will use the overloaded assignment operator defined in the base class to assign one object of base class type to another object of base class type. If we assign an object of derived class to another object of derived class then the overloaded assignment operator defined in the derived class will be used to assign the base class subobjects.
New C++ Style Casts
A cast tells the compiler, "Trust me, I know what I'm doing." When you lie, programs crash.)
The old-style cast could be used for several different purposes. In particular, it was commonly used for - changing constness: (char*)ptr_to_const_char - converting a value to a value of a different type: (int)floating_value - navigating a hierarchy: (derived*)ptr_to_base - type "punning": (int*)ptr_to_void (Type punning generally means treating an object, particularly a pointer, as an object of a different type.)
When you see a cast expression like "(T)(expr)" it is often hard to tell why the cast is there. Also, it is often hard to tell whether the cast is likely to be dangerous or nonportable. Finally, there is no way to scan a source file and reliably find every cast, unless you have a "smart editor" that can fully parse C++ source code.
C++ introduced four new cast operators to address those problems: Each cast is intended for a particular purpose (although there is some overlap), and each cast uses a new keyword that can be found easily with any text editor. ---> static_cast: primarily for value conversion - can perform any conversion which is allowed implicitly -- Whenever you can make an implicit conversion from one type to another, you can make a static_cast in the opposite direction. You can, for example, use static casts for base to derived conversions if the base class is non-virtual. - cannot remove constness -- used for user-defined, standard, or implicit type conversions.
---->dynamic_cast: primarily for hierarchy navigation - can upcast a ptr_to_derived to any of its unambiguous base classes - can downcast a ptr_to_base (including virtual base classes) to any unambiguous derived class if the class is polymorphic. Indicates failure if the object isn't really the right type. - can cast "sideways" in a hierarchy if the class is polymorphic - cannot remove constness --It can only be used for types with run-time type information, i.e. classes with at least one virtual member function used for navigation in a class hierarchy when static_cast is not appropriate.
---->reinterpret_cast: primarily for type punning - can convert pointers to integer types and vice versa - can convert a pointer to an unrelated pointer type - results are implementation-defined and might not work - cannot remove constness used for non-portable conversion between pointer types,or between a pointer and an integer type.
---->const_cast: primarily to remove constness - can change the const and volatile specifiers of a type - cannot otherwise change the type used for remove const or volatile from a type.
The old-style cast is now defined as a static_cast or reinterpret_cast possibly followed by a const_cast. (The only dynamic_casts that an old-style cast can perform can also be performed by a static_cast. If an old-style cast could be performed by both a static_cast and a reinterpret_cast, the static_cast interpretation is chosen.)
Differences Between static_cast and reinterpret_cast: The operators static_cast and reinterpret_cast are similar: they both convert an object to an object of a different type. However, they aren't interchangeable. Static_cast uses the type information available at compile time to perform the conversion, making the necessary adjustments between the source and target types. Thus, its operation is relatively safe. On the other hand, reinterpret_cast simply reinterprets the bit pattern of a given object without changing its binary representation. To show the difference between the two, let's look at the following example:
int n = 9; double d = static_cast < double > (n);
In this example, we convert an int to a double. The binary representation of these types is very different. In order to convert the int 9 to a double, static_cast needs to properly pad the additional bytes of d. As expected, the result of the conversion is 9.0. Now let's see how reinterpret_cast behaves in this context:
int n = 9; double d = reinterpret_cast< double & > (n);
This time the results are unpredictable. After the cast, d contains a garbage value rather than 9.0. This is because reinterpret_cast simply copied the bit pattern of n into d as is, without making the necessary adjustments. For this reason, you should use reinterpret_cast sparingly and judiciously.
Downcast from a virtual base class is illegal but why?
Because there may be more than one derived class subobject of the same object with the same type and the same virtual base class object. In that case, there is no way to tell which of the derived class subobjects was intended. For example: class V { };
class B: public virtual V { };
class D: public B { }
class E: public B, public D { };
Every object of class E now contains a B part and a D part. The D part contains a(nother) B part. Each B part refers to the same V object. So suppose we have:
V* vp;
B* bp = (B*) vp;
where vp really points at the V part of an E object. The cast is ambiguous -- there is no way to tell which B was intended.
//////////////////////////////////////////////////////////////////////////////////////////// ///// class A { };
class B:A { };
void main() { B* b = new B(); A* a; a = reinterpret_cast(b);//will work a = static_cast(b);//will not work } //////////////////////////////////////////////////////////////////////////////////////////// ///
|
Responses
|
| Author: rambabu 14 May 2008 | Member Level: Silver Points : 2 | very nice . these are good programs in c++.
|
|
|