Q. What is Singleton Class? Explain.
C++ Implementation:
#include <iostream>
using namespace std;
// Singleton class
class Singleton{
static bool isInstance;
static Singleton* singleInstance;
Singleton(){
cout << "Singleton constructor called" << endl;
}
public:
void func1(){
cout << "func1() of Singleton called" << endl;
}
~Singleton(){
cout << "Destructor of Singleton called" << endl;
isInstance = false;
singleInstance = NULL;
}
static Singleton* getInstance();
static bool removeInstance();
};
bool Singleton::isInstance = false;
Singleton* Singleton::singleInstance = NULL;
Singleton* Singleton::getInstance(){
if(!isInstance){
singleInstance = new Singleton();
isInstance = true;
}
return singleInstance;
}
bool Singleton::removeInstance(){
if(isInstance){
delete singleInstance;
return true;
}
return false;
}
// main function
int main(int argc, char* argv[])
{
Singleton* sp1, *sp2;
sp1 = Singleton::getInstance();
sp1->func1();
sp2 = Singleton::getInstance();
sp2->func1();
cout << "address of sp1 = " << sp1 << endl;
cout << "address of sp2 = " << sp2 << endl;
Singleton::removeInstance();
Singleton* sp3 = Singleton::getInstance();
sp3->func1();
Singleton::removeInstance();
return 0;
}
Output:
Q. What are the differences between const int*, int * const, and const int * const?
Solution:
const int *x : Pointer to a const int (Value pointed to by x can’t change)
int * const x : Const pointer to an int (x cannot point to a different location)
const int *const x : Const pointer to a const int (Both the pointer and the value pointed to cannot change)
The first const can be on either side of type specifier(int here). So
const int * <==> int const *
const int * const <==> int const * const
Example:
#include <iostream>
using namespace std;
int main()
{
int a = 5, b = 10, c = 15;
int const *p1 = &a; // pointer to integer constant
int * const p2 = &b; // constant pointer to integer
int const * const p3 =&c; // constant pointer to constant int
p1 = &b; // CORRECT..not a const pointer,so address can change
*p1 = 0; // WRONG...value pointed to by p1 can't be modified
p2 = &c; // WRONG.. const pointer..so address can't change
*p2 = 0; // CORRECT
p3 = &a; // WRONG... const pointer
*p3 = 0; // WRONG..points to constant value
return 0;
}
But we can change the values pointed to by p1, p2, and p3 in the above example by directly assigning new values to a, b and c.
Q. What are 'volatile' variables ?
Solution:
Q. What is qsort() function ?
qsort function
Q. What is the difference between a copy constructor and an overloaded assignment operator?
Ans: A copy constructor constructs a new object by using the content of the argument object. An overloaded assignment operator assigns the contents of an existing object to another existing object of the same class.
The intent of the Singleton pattern as defined in Design Patterns is to "ensure a class has only one instance, and provide a global point of access to it".
What problem does this solve, or put another way, what is our motivation to use it? In nearly every application, there is a need to have an area from which to globally access and maintain some type of data. There are also cases in object-oriented (OO) systems where there should be only one class, or a predefined number of instances of a class, running at any given time. For example, when a class is being used to maintain an incremental counter, the simple counter class needs to keep track of an integer value that is being used in multiple areas of an application. The class needs to be able to increment this counter as well as return the current value. For this situation, the desired class behavior would be to have exactly one instance of a class that maintains the integer and nothing more.
At first glance, one might be tempted to create an instance of a counter class as a just a static global variable. This is a common technique but really only solves part of the problem; it solves the problem of global accessibility, but does nothing to ensure that there is only one instance of the class running at any given time. The responsibility of having only one instance of the class should fall on the class itself and not on the user of the class. The users of the class should always be free from having to monitor and control the number of running instances of the class.
What is needed is a way to control how class instances are created and then ensure that only one gets created at any given time. This would give us exactly the behavior we require and free a client from having to know any class details.
Logical Model
The model for a singleton is very straightforward. There is (usually) only one singleton instance. Clients access the singleton instance through one well-known access point. The client in this case is an object that needs access to a sole instance of a singleton. Figure 1 shows this relationship graphically.
Figure 1. Singleton pattern logical model
Physical Model
The physical model for the Singleton pattern is also very simple. However, there are several slightly different ways that singletons have been implemented over time. Let's look at the original GoF singleton implementation. Figure 2 shows a UML model of the original Singleton pattern as defined in Design Patterns.
Figure 2. Singleton pattern physical model from design patterns
What we see is a simple class diagram showing that there is a private static property of a singleton object as well as public method Instance() that returns this same property. This is really the core of what makes a singleton. The other properties and methods are there to show additional operations that may be allowed on the class.
source: Exploring the Singleton design pattern, MSDN
C++ Implementation:
#include <iostream>
using namespace std;
// Singleton class
class Singleton{
static bool isInstance;
static Singleton* singleInstance;
Singleton(){
cout << "Singleton constructor called" << endl;
}
public:
void func1(){
cout << "func1() of Singleton called" << endl;
}
~Singleton(){
cout << "Destructor of Singleton called" << endl;
isInstance = false;
singleInstance = NULL;
}
static Singleton* getInstance();
static bool removeInstance();
};
bool Singleton::isInstance = false;
Singleton* Singleton::singleInstance = NULL;
Singleton* Singleton::getInstance(){
if(!isInstance){
singleInstance = new Singleton();
isInstance = true;
}
return singleInstance;
}
bool Singleton::removeInstance(){
if(isInstance){
delete singleInstance;
return true;
}
return false;
}
// main function
int main(int argc, char* argv[])
{
Singleton* sp1, *sp2;
sp1 = Singleton::getInstance();
sp1->func1();
sp2 = Singleton::getInstance();
sp2->func1();
cout << "address of sp1 = " << sp1 << endl;
cout << "address of sp2 = " << sp2 << endl;
Singleton::removeInstance();
Singleton* sp3 = Singleton::getInstance();
sp3->func1();
Singleton::removeInstance();
return 0;
}
Output:
Singleton constructor called func1() of Singleton called func1() of Singleton called address of sp1 = 0x602010 address of sp2 = 0x602010 Destructor of Singleton called Singleton constructor called func1() of Singleton called Destructor of Singleton called
Note that both sp1 and sp2 are pointing to the same address.
Q. What are the differences between const int*, int * const, and const int * const?
Solution:
const int *x : Pointer to a const int (Value pointed to by x can’t change)
int * const x : Const pointer to an int (x cannot point to a different location)
const int *const x : Const pointer to a const int (Both the pointer and the value pointed to cannot change)
The first const can be on either side of type specifier(int here). So
const int * <==> int const *
const int * const <==> int const * const
Example:
#include <iostream>
using namespace std;
int main()
{
int a = 5, b = 10, c = 15;
int const *p1 = &a; // pointer to integer constant
int * const p2 = &b; // constant pointer to integer
int const * const p3 =&c; // constant pointer to constant int
p1 = &b; // CORRECT..not a const pointer,so address can change
*p1 = 0; // WRONG...value pointed to by p1 can't be modified
p2 = &c; // WRONG.. const pointer..so address can't change
*p2 = 0; // CORRECT
p3 = &a; // WRONG... const pointer
*p3 = 0; // WRONG..points to constant value
return 0;
}
But we can change the values pointed to by p1, p2, and p3 in the above example by directly assigning new values to a, b and c.
Q. What are 'volatile' variables ?
Solution:
Q. What is qsort() function ?
qsort function
void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));
Sort elements of array
Sorts the num elements of the array pointed by base, each element size bytes long, using the compar function to determine the order.
The sorting algorithm used by this function compares pairs of elements by calling the specified compar function with pointers to them as argument.
The function does not return any value, but modifies the content of the array pointed by base reordering its elements as defined by compar.
The order of equivalent elements is undefined.
Sorts the num elements of the array pointed by base, each element size bytes long, using the compar function to determine the order.
The sorting algorithm used by this function compares pairs of elements by calling the specified compar function with pointers to them as argument.
The function does not return any value, but modifies the content of the array pointed by base reordering its elements as defined by compar.
The order of equivalent elements is undefined.
Parameters
- base
- Pointer to the first object of the array to be sorted, converted to a
void*
. - num
- Number of elements in the array pointed by base.
size_t is an unsigned integral type. - size
- Size in bytes of each element in the array.
size_t is an unsigned integral type. - compar
- Pointer to a function that compares two elements.
This function is called repeatedly by qsort to compare two elements. It shall follow the following prototype:
int compar (const void* p1, const void* p2);
Taking two pointers as arguments (both converted to const void*). The function defines the order of the elements by returning (in a stable and transitive manner):
return value meaning <0
The element pointed by p1 goes before the element pointed by p2 0
The element pointed by p1 is equivalent to the element pointed by p2 >0
The element pointed by p1 goes after the element pointed by p2 - Source: www.cplusplus.com
Q. Is it possible to have Virtual Constructor? If yes, how? If not, Why not possible?
Ans: There is nothing like Virtual Constructor. The Constructor can’t be virtual as the constructor is a code which is responsible for creating an instance of a class and it can’t be delegated to any other object by virtual keyword means.
Q. What is constructor or ctor?
Ans: Constructor creates an object and initializes it. It also creates vtable for virtual functions. It is different from other methods in a class.
Q. Is it possible to have Virtual Destructor?
Ans: Yes there is a Virtual Destructor. A destructor can be virtual as it is possible as at run-time depending on the type of object caller is calling to, proper destructor will be called.
Q. What is the difference between a copy constructor and an overloaded assignment operator?
Ans: A copy constructor constructs a new object by using the content of the argument object. An overloaded assignment operator assigns the contents of an existing object to another existing object of the same class.
Q. Can a copy constructor accept an object of the same class as parameter, instead of reference of the object?
Ans: No. It is specified in the definition of the copy constructor itself. It should generate an error if a programmer specifies a copy constructor with a first argument that is an object and not a reference.
Q. What is conversion constructor?
Ans: constructor with a single argument makes that constructor as conversion ctor and it can be used for type conversion.
for example:
class XYZ
{
public:
XYZ( int i );
};
XYZ Obj = 10 ; // assigning int 10 XYZ object
Q. What is conversion operator??
Ans: class can have a public method for specific data type conversions.
for example:
class A
{
double value;
public:
A(int i )
operator double()
{
return value;
}
};
A AObject;
double i = AObject;//assigning object to variable of type double
now conversion operator gets called to assign the value.
Q. What's the order that objects in an array are destructed?
Ans: In reverse order of construction: First constructed, last destructed.
In the following example, the order for destructors will be a[9], a[8], ..., a[1], a[0]:
void userCode()
{
XYZ a[10];
...
}
Q. Can I overload the destructor for my class?
Ans: No.
You can have only one destructor for a class Fred. It's always called Fred::~Fred(). It never takes any parameters, and it never returns anything.
You can't pass parameters to the destructor anyway, since you never explicitly call a destructor (well, almost never).
Q. Should I explicitly call a destructor on a local variable?
Ans: No!
The destructor will get called again at the close } of the block in which the local was created.
This is a guarantee of the language; it happens automatically; there's no way to stop it from happening. But you can get really bad results from calling a destructor on the same object a second time!
Q. But can I explicitly call a destructor if I've allocated my object with new?
Ans: Probably not.
Unless you used placement new, you should simply delete the object rather than explicitly
calling the destructor. For example, suppose you allocated the object via a typical new
expression:
Fred* p = new Fred();
Then the destructor Fred::~Fred() will automatically get called when you delete it via:
delete p; // Automatically calls p->~Fred()
You should not explicitly call the destructor, since doing so won't release the memory that was
allocated for the Fred object itself. Remember: delete p does two things: it calls the destructor
and it deallocates the memory.
Q. What is "placement new" and why would I use it?
Ans: There are many uses of placement new. The simplest use is to place an object at a particular location in memory. This is done by supplying the place as a pointer parameter to the new part of a new expression:
#include // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)]; // Line #1
void* place = memory; // Line #2
Fred* f = new(place) Fred(); // Line #3 (see "DANGER" below)
// The pointers f and place will be equal
...
}
Line #1 creates an array of sizeof(Fred) bytes of memory, which is big enough to hold a Fred
object. Line #2 creates a pointer place that points to the first byte of this memory (experienced C programmers will note that this step was unnecessary; it's there only to make the code more
obvious). Line #3 essentially just calls the constructor Fred::Fred(). The this pointer in the Fred
constructor will be equal to place. The returned pointer f will therefore be equal to place.
ADVICE: Don't use this "placement new" syntax unless you have to. Use it only when you really
care that an object is placed at a particular location in memory. For example, when your
hardware has a memory-mapped I/O timer device, and you want to place a Clock object at that
memory location.
DANGER: You are taking sole responsibility that the pointer you pass to the "placement new" operator points to a region of memory that is big enough and is properly aligned for the object
type that you're creating. Neither the compiler nor the run-time system make any attempt to check whether you did this right. If your Fred class needs to be aligned on a 4 byte boundary but you supplied a location that isn't properly aligned, you can have a serious disaster on your hands(if you don't know what "alignment" means, please don't use the placement new syntax).
You are also solely responsible for destructing the placed object. This is done by explicitly calling the destructor:
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
...
f->~Fred(); // Explicitly call the destructor for the placed object
}
This is about the only time you ever explicitly call a destructor.
Q. Can one constructor of a class call another constructor of the same class to initialize the this object?
Ans: Nope.
Let's work an example. Suppose you want your constructor Foo::Foo(char) to call another
constructor of the same class, say Foo::Foo(char,int), in order that Foo::Foo(char,int) would help initialize the this object. Unfortunately there's no way to do this in C++.
Some people do it anyway. Unfortunately it doesn't do what they want. For example, the line
Foo(x, 0); does not call Foo::Foo(char,int) on the this object. Instead it calls Foo::Foo(char,int) to initialize a temporary, local object (not this), then it immediately destructs that temporary when control flows over the ;.
class Foo {
public:
Foo(char x);
Foo(char x, int y);
...
};
Foo::Foo(char x)
{ ...
Foo(x, 0); // this line does NOT help initialize the this object!!
...
}
You can sometimes combine two constructors via a default parameter:
class Foo {
public:
Foo(char x, int y=0); // this line combines the two constructors
...
};
If that doesn't work, e.g., if there isn't an appropriate default parameter that combines the two
constructors, sometimes you can share their common code in a private init() member function:
class Foo {
public:
Foo(char x);
Foo(char x, int y);
...
private:
void init(char x, int y);
};
Foo::Foo(char x)
{
init(x, int(x) + 7);
...
}
Foo::Foo(char x, int y)
{
init(x, y);
...
}
void Foo::init(char x, int y)
{
...
}
BTW do NOT try to achieve this via placement new. Some people think they can say new(this)
Foo(x, int(x)+7) within the body of Foo::Foo(char). However that is bad, bad, bad. Please don't
write me and tell me that it seems to work on your particular version of your particular compiler;
it's bad. Constructors do a bunch of little magical things behind the scenes, but that bad technique steps on those partially constructed bits. Just say no.
Q. Is the default constructor for Fred always Fred::Fred()?
Ans: No. A "default constructor" is a constructor that can be called with no arguments. One
example of this is a constructor that takes no parameters:
class Fred {
public:
Fred(); // Default constructor: can be called with no args
...
};
Another example of a "default constructor" is one that can take arguments, provided they are
given default values:
class Fred {
public:
Fred(int i=3, int j=5); // Default constructor: can be called with no args
...
};
Q. Which constructor gets called when I create an array of Fred objects?
Ans: Fred's default constructor (except as discussed below).
class Fred {
public:
Fred();
...
};
int main()
{
Fred a[10]; calls the default constructor 10 times
Fred* p = new Fred[10]; calls the default constructor 10 times
...
}
If your class doesn't have a default constructor, you'll get a compile-time error when you attempt
to create an array using the above simple syntax:
class Fred {
public:
Fred(int i, int j); assume there is no default constructor
...
};
int main()
{
Fred a[10]; ERROR: Fred doesn't have a default constructor
Fred* p = new Fred[10]; ERROR: Fred doesn't have a default constructor
...
}
However, even if your class already has a default constructor, you should try to use std::vector
rather than an array (arrays are evil). std::vector lets you decide to use any constructor, not just
the default constructor:
#include
int main()
{
std::vector a(10, Fred(5,7)); the 10 Fred objects in std::vector a will be initialized with Fred(5,7)
...
}
Even though you ought to use a std::vector rather than an array, there are times when an array
might be the right thing to do, and for those, you might need the "explicit initialization of arrays"
syntax. Here's how:
class Fred {
public:
Fred(int i, int j); assume there is no default constructor
...
};
int main()
{
Fred a[10] = {
Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), // The 10 Fred objects are
Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7) // initialized using Fred(5,7)
};
...
}
Of course you don't have to do Fred(5,7) for every entry you can put in any numbers you want, even parameters or other variables.
Finally, you can use placement-new to manually initialize the elements of the array. Warning: it's ugly: the raw array can't be of type Fred, so you'll need a bunch of pointer-casts to do things like compute array index operations. Warning: it's compiler- and hardware-dependent: you'll need to make sure the storage is aligned with an alignment that is at least as strict as is required for objects of class Fred. Warning: it's tedious to make it exception-safe: you'll need to manually destruct the elements, including in the case when an exception is thrown part-way through the
loop that calls the constructors. But if you really want to do it anyway, read up on placement-new. (BTW placement-new is the magic that is used inside of std::vector. The complexity of getting everything right is yet another reason to use std::vector.)
Ans: No. It is specified in the definition of the copy constructor itself. It should generate an error if a programmer specifies a copy constructor with a first argument that is an object and not a reference.
Q. What is conversion constructor?
Ans: constructor with a single argument makes that constructor as conversion ctor and it can be used for type conversion.
for example:
class XYZ
{
public:
XYZ( int i );
};
XYZ Obj = 10 ; // assigning int 10 XYZ object
Q. What is conversion operator??
Ans: class can have a public method for specific data type conversions.
for example:
class A
{
double value;
public:
A(int i )
operator double()
{
return value;
}
};
A AObject;
double i = AObject;//assigning object to variable of type double
now conversion operator gets called to assign the value.
Q. What's the order that objects in an array are destructed?
Ans: In reverse order of construction: First constructed, last destructed.
In the following example, the order for destructors will be a[9], a[8], ..., a[1], a[0]:
void userCode()
{
XYZ a[10];
...
}
Q. Can I overload the destructor for my class?
Ans: No.
You can have only one destructor for a class Fred. It's always called Fred::~Fred(). It never takes any parameters, and it never returns anything.
You can't pass parameters to the destructor anyway, since you never explicitly call a destructor (well, almost never).
Q. Should I explicitly call a destructor on a local variable?
Ans: No!
The destructor will get called again at the close } of the block in which the local was created.
This is a guarantee of the language; it happens automatically; there's no way to stop it from happening. But you can get really bad results from calling a destructor on the same object a second time!
Q. But can I explicitly call a destructor if I've allocated my object with new?
Ans: Probably not.
Unless you used placement new, you should simply delete the object rather than explicitly
calling the destructor. For example, suppose you allocated the object via a typical new
expression:
Fred* p = new Fred();
Then the destructor Fred::~Fred() will automatically get called when you delete it via:
delete p; // Automatically calls p->~Fred()
You should not explicitly call the destructor, since doing so won't release the memory that was
allocated for the Fred object itself. Remember: delete p does two things: it calls the destructor
and it deallocates the memory.
Q. What is "placement new" and why would I use it?
Ans: There are many uses of placement new. The simplest use is to place an object at a particular location in memory. This is done by supplying the place as a pointer parameter to the new part of a new expression:
#include // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)]; // Line #1
void* place = memory; // Line #2
Fred* f = new(place) Fred(); // Line #3 (see "DANGER" below)
// The pointers f and place will be equal
...
}
Line #1 creates an array of sizeof(Fred) bytes of memory, which is big enough to hold a Fred
object. Line #2 creates a pointer place that points to the first byte of this memory (experienced C programmers will note that this step was unnecessary; it's there only to make the code more
obvious). Line #3 essentially just calls the constructor Fred::Fred(). The this pointer in the Fred
constructor will be equal to place. The returned pointer f will therefore be equal to place.
ADVICE: Don't use this "placement new" syntax unless you have to. Use it only when you really
care that an object is placed at a particular location in memory. For example, when your
hardware has a memory-mapped I/O timer device, and you want to place a Clock object at that
memory location.
DANGER: You are taking sole responsibility that the pointer you pass to the "placement new" operator points to a region of memory that is big enough and is properly aligned for the object
type that you're creating. Neither the compiler nor the run-time system make any attempt to check whether you did this right. If your Fred class needs to be aligned on a 4 byte boundary but you supplied a location that isn't properly aligned, you can have a serious disaster on your hands(if you don't know what "alignment" means, please don't use the placement new syntax).
You are also solely responsible for destructing the placed object. This is done by explicitly calling the destructor:
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
...
f->~Fred(); // Explicitly call the destructor for the placed object
}
This is about the only time you ever explicitly call a destructor.
Q. Can one constructor of a class call another constructor of the same class to initialize the this object?
Ans: Nope.
Let's work an example. Suppose you want your constructor Foo::Foo(char) to call another
constructor of the same class, say Foo::Foo(char,int), in order that Foo::Foo(char,int) would help initialize the this object. Unfortunately there's no way to do this in C++.
Some people do it anyway. Unfortunately it doesn't do what they want. For example, the line
Foo(x, 0); does not call Foo::Foo(char,int) on the this object. Instead it calls Foo::Foo(char,int) to initialize a temporary, local object (not this), then it immediately destructs that temporary when control flows over the ;.
class Foo {
public:
Foo(char x);
Foo(char x, int y);
...
};
Foo::Foo(char x)
{ ...
Foo(x, 0); // this line does NOT help initialize the this object!!
...
}
You can sometimes combine two constructors via a default parameter:
class Foo {
public:
Foo(char x, int y=0); // this line combines the two constructors
...
};
If that doesn't work, e.g., if there isn't an appropriate default parameter that combines the two
constructors, sometimes you can share their common code in a private init() member function:
class Foo {
public:
Foo(char x);
Foo(char x, int y);
...
private:
void init(char x, int y);
};
Foo::Foo(char x)
{
init(x, int(x) + 7);
...
}
Foo::Foo(char x, int y)
{
init(x, y);
...
}
void Foo::init(char x, int y)
{
...
}
BTW do NOT try to achieve this via placement new. Some people think they can say new(this)
Foo(x, int(x)+7) within the body of Foo::Foo(char). However that is bad, bad, bad. Please don't
write me and tell me that it seems to work on your particular version of your particular compiler;
it's bad. Constructors do a bunch of little magical things behind the scenes, but that bad technique steps on those partially constructed bits. Just say no.
Q. Is the default constructor for Fred always Fred::Fred()?
Ans: No. A "default constructor" is a constructor that can be called with no arguments. One
example of this is a constructor that takes no parameters:
class Fred {
public:
Fred(); // Default constructor: can be called with no args
...
};
Another example of a "default constructor" is one that can take arguments, provided they are
given default values:
class Fred {
public:
Fred(int i=3, int j=5); // Default constructor: can be called with no args
...
};
Q. Which constructor gets called when I create an array of Fred objects?
Ans: Fred's default constructor (except as discussed below).
class Fred {
public:
Fred();
...
};
int main()
{
Fred a[10]; calls the default constructor 10 times
Fred* p = new Fred[10]; calls the default constructor 10 times
...
}
If your class doesn't have a default constructor, you'll get a compile-time error when you attempt
to create an array using the above simple syntax:
class Fred {
public:
Fred(int i, int j); assume there is no default constructor
...
};
int main()
{
Fred a[10]; ERROR: Fred doesn't have a default constructor
Fred* p = new Fred[10]; ERROR: Fred doesn't have a default constructor
...
}
However, even if your class already has a default constructor, you should try to use std::vector
rather than an array (arrays are evil). std::vector lets you decide to use any constructor, not just
the default constructor:
#include
int main()
{
std::vector a(10, Fred(5,7)); the 10 Fred objects in std::vector a will be initialized with Fred(5,7)
...
}
Even though you ought to use a std::vector rather than an array, there are times when an array
might be the right thing to do, and for those, you might need the "explicit initialization of arrays"
syntax. Here's how:
class Fred {
public:
Fred(int i, int j); assume there is no default constructor
...
};
int main()
{
Fred a[10] = {
Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), // The 10 Fred objects are
Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7), Fred(5,7) // initialized using Fred(5,7)
};
...
}
Of course you don't have to do Fred(5,7) for every entry you can put in any numbers you want, even parameters or other variables.
Finally, you can use placement-new to manually initialize the elements of the array. Warning: it's ugly: the raw array can't be of type Fred, so you'll need a bunch of pointer-casts to do things like compute array index operations. Warning: it's compiler- and hardware-dependent: you'll need to make sure the storage is aligned with an alignment that is at least as strict as is required for objects of class Fred. Warning: it's tedious to make it exception-safe: you'll need to manually destruct the elements, including in the case when an exception is thrown part-way through the
loop that calls the constructors. But if you really want to do it anyway, read up on placement-new. (BTW placement-new is the magic that is used inside of std::vector. The complexity of getting everything right is yet another reason to use std::vector.)
Q. What is printf() function in C ?
Ans:
Writes the C string pointed by format to the standard output (stdout). If format includes format specifiers(subsequences beginning with %), the additional arguments following format are formatted and inserted in the resulting string replacing their respective specifiers.
If a writing error occurs, the error indicator (ferror) is set and a negative number is returned.
If a multibyte character encoding error occurs while writing wide characters, errno is set to EILSEQ and a negative number is returned.
Output:
Q. What is fgetc() function in C ?
Returns the character currently pointed by the internal file position indicator of the specified stream. The internal file position indicator is then advanced to the next character.
If the stream is at the end-of-file when called, the function returns EOF and sets the end-of-file indicator for the stream (feof).
If a read error occurs, the function returns EOF and sets the error indicator for the stream (ferror).
fgetc and getc are equivalent, except that getc may be implemented as a macro in some libraries.
The return type is int to accommodate for the special value EOF, which indicates failure:
If the position indicator was at the end-of-file, the function returns EOF and sets the eof indicator (feof) of stream.
If some other reading error happens, the function also returns EOF, but sets its error indicator (ferror) instead.
This program reads an existing file called myfile.txt character by character and uses the n variable to count how many dollar characters ($) the file contains.
Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.
A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.
A terminating null character is automatically appended after the characters copied to str.
Notice that fgets is quite different from gets: not only fgets accepts a stream argument, but also allows to specify the maximum size of str and includes in the string any ending newline character.
If the end-of-file is encountered while attempting to read a character, the eof indicator is set (feof). If this happens before any characters could be read, the pointer returned is a null pointer (and the contents of str remain unchanged).
If a read error occurs, the error indicator (ferror) is set and a null pointer is also returned (but the contents pointed by str may have changed).
This example reads the first line of myfile.txt or the first 99 characters, whichever comes first, and prints them on the screen.
Sets the position indicator associated with the stream to a new position.
For streams open in binary mode, the new position is defined by adding offset to a reference position specified byorigin.
For streams open in text mode, offset shall either be zero or a value returned by a previous call to ftell, and originshall necessarily be SEEK_SET.
If the function is called with other values for these arguments, support depends on the particular system and library implementation (non-portable).
The end-of-file internal indicator of the stream is cleared after a successful call to this function, and all effects from previous calls to ungetc on this stream are dropped.
On streams open for update (read+write), a call to fseek allows to switch between reading and writing.
Otherwise, it returns non-zero value.
If a read or write error occurs, the error indicator (ferror) is set.
After this code is successfully executed, the file example.txt contains:
source: www.cpluscplus.com
int i2 = 32779; //00000000 00000000 10000000 00001011
Ans:
int printf ( const char * format, ... );
Print formatted data to stdout
Parameters
- format
- C string that contains the text to be written to stdout.
It can optionally contain embedded format specifiers that are replaced by the values specified in subsequent additional arguments and formatted as requested.
A format specifier follows this prototype: [see compatibility note below]
%[flags][width][.precision][length]specifier
Where the specifier character at the end is the most significant component, since it defines the type and the interpretation of its corresponding argument:
specifier Output Example d or i Signed decimal integer 392 u Unsigned decimal integer 7235 o Unsigned octal 610 x Unsigned hexadecimal integer 7fa X Unsigned hexadecimal integer (uppercase) 7FA f Decimal floating point, lowercase 392.65 F Decimal floating point, uppercase 392.65 e Scientific notation (mantissa/exponent), lowercase 3.9265e+2 E Scientific notation (mantissa/exponent), uppercase 3.9265E+2 g Use the shortest representation: %e or %f 392.65 G Use the shortest representation: %E or %F 392.65 a Hexadecimal floating point, lowercase -0xc.90fep-2 A Hexadecimal floating point, uppercase -0XC.90FEP-2 c Character a s String of characters sample p Pointer address b8000000 n Nothing printed.
The corresponding argument must be a pointer to a signed int.
The number of characters written so far is stored in the pointed location.% A % followed by another % character will write a single % to the stream. %
The format specifier can also contain sub-specifiers: flags, width, .precision and modifiers (in that order), which are optional and follow these specifications:
flags description - Left-justify within the given field width; Right justification is the default (see width sub-specifier). + Forces to preceed the result with a plus or minus sign (+ or -) even for positive numbers. By default, only negative numbers are preceded with a - sign. (space) If no sign is going to be written, a blank space is inserted before the value. # Used with o, x or X specifiers the value is preceeded with 0, 0x or 0X respectively for values different than zero.
Used with a, A, e, E, f, F, g or G it forces the written output to contain a decimal point even if no more digits follow. By default, if no digits follow, no decimal point is written.0 Left-pads the number with zeroes (0) instead of spaces when padding is specified (see width sub-specifier).
width description (number) Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger. * The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
.precision description .number For integer specifiers (d, i, o, u, x, X): precision specifies the minimum number of digits to be written. If the value to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A precision of 0 means that no character is written for the value 0.
For a, A, e, E, f and F specifiers: this is the number of digits to be printed after the decimal point (by default, this is 6).
For g and G specifiers: This is the maximum number of significant digits to be printed.
For s: this is the maximum number of characters to be printed. By default all characters are printed until the ending null character is encountered.
If the period is specified without an explicit value for precision, 0 is assumed..* The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.
The length sub-specifier modifies the length of the data type. This is a chart showing the types used to interpret the corresponding arguments with and without length specifier (if a different type is used, the proper type promotion or conversion is performed, if allowed):
specifiers length d i u o x X f F e E g G a A c s p n (none) int unsigned int double int char* void* int* hh signed char unsigned char signed char* h short int unsigned short int short int* l long int unsigned long int wint_t wchar_t* long int* ll long long int unsigned long long int long long int* j intmax_t uintmax_t intmax_t* z size_t size_t size_t* t ptrdiff_t ptrdiff_t ptrdiff_t* L long double
Note: Yellow rows indicate specifiers and sub-specifiers introduced by C99. See <cinttypes> for the specifiers for extended types. - ... (additional arguments)
- Depending on the format string, the function may expect a sequence of additional arguments, each containing a value to be used to replace a format specifier in the format string (or a pointer to a storage location, for n).
There should be at least as many of these arguments as the number of values specified in the format specifiers. Additional arguments are ignored by the function.
Return Value
On success, the total number of characters written is returned.If a writing error occurs, the error indicator (ferror) is set and a negative number is returned.
If a multibyte character encoding error occurs while writing wide characters, errno is set to EILSEQ and a negative number is returned.
Example
|
|
Output:
Characters: a A Decimals: 1977 650000 Preceding with blanks: 1977 Preceding with zeros: 0000001977 Some different radices: 100 64 144 0x64 0144 floats: 3.14 +3e+000 3.141600E+000 Width trick: 10 A string |
Q. What is fgetc() function in C ?
Ans:
int fgetc ( FILE * stream );
Get character from stream
If the stream is at the end-of-file when called, the function returns EOF and sets the end-of-file indicator for the stream (feof).
If a read error occurs, the function returns EOF and sets the error indicator for the stream (ferror).
fgetc and getc are equivalent, except that getc may be implemented as a macro in some libraries.
Parameters
- stream
- Pointer to a FILE object that identifies an input stream.
Return Value
On success, the character read is returned (promoted to an int value).The return type is int to accommodate for the special value EOF, which indicates failure:
If the position indicator was at the end-of-file, the function returns EOF and sets the eof indicator (feof) of stream.
If some other reading error happens, the function also returns EOF, but sets its error indicator (ferror) instead.
Example
|
|
This program reads an existing file called myfile.txt character by character and uses the n variable to count how many dollar characters ($) the file contains.
Q. What is fgets() function in C ?
Ans:
char * fgets ( char * str, int num, FILE * stream );
Get string from stream
A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.
A terminating null character is automatically appended after the characters copied to str.
Notice that fgets is quite different from gets: not only fgets accepts a stream argument, but also allows to specify the maximum size of str and includes in the string any ending newline character.
Parameters
Return Value
On success, the function returns str.If the end-of-file is encountered while attempting to read a character, the eof indicator is set (feof). If this happens before any characters could be read, the pointer returned is a null pointer (and the contents of str remain unchanged).
If a read error occurs, the error indicator (ferror) is set and a null pointer is also returned (but the contents pointed by str may have changed).
Example
|
|
This example reads the first line of myfile.txt or the first 99 characters, whichever comes first, and prints them on the screen.
Q. What is fseek() function in C ?
Ans:
int fseek ( FILE * stream, long int offset, int origin );
Reposition stream position indicator
For streams open in binary mode, the new position is defined by adding offset to a reference position specified byorigin.
For streams open in text mode, offset shall either be zero or a value returned by a previous call to ftell, and originshall necessarily be SEEK_SET.
If the function is called with other values for these arguments, support depends on the particular system and library implementation (non-portable).
The end-of-file internal indicator of the stream is cleared after a successful call to this function, and all effects from previous calls to ungetc on this stream are dropped.
On streams open for update (read+write), a call to fseek allows to switch between reading and writing.
Parameters
- stream
- Pointer to a FILE object that identifies the stream.
- offset
- Binary files: Number of bytes to offset from origin.
Text files: Either zero, or a value returned by ftell. - origin
- Position used as reference for the offset. It is specified by one of the following constants defined in <cstdio>exclusively to be used as arguments for this function:
Constant Reference position SEEK_SET Beginning of file SEEK_CUR Current position of the file pointer SEEK_END End of file *
Return Value
If successful, the function returns zero.Otherwise, it returns non-zero value.
If a read or write error occurs, the error indicator (ferror) is set.
Example
|
|
After this code is successfully executed, the file example.txt contains:
This is a sample |
Q. What happens if an 'int' value is type-casted to 'short' in C/C++ ?
Ans:
Only the 16 bits from LSB side are copied irrespective of taking into account the initial sign-bit.
Example:
#include <iostream>
using namespace std;
int main()
{
int i1 = 16395; //00000000 00000000 01000000 00001011int i2 = 32779; //00000000 00000000 10000000 00001011
short s1 = static_cast<short>(i1);
short s2 = static_cast<short>(i2);
cout << "s1 = " << s1 << endl;
cout << "s2 = " << s2 << endl;
return 0;
}
Output:
s1 = 16395 s2 = -32757
No comments :
Post a Comment