Tricks and Traps of C++


C++ is only mostly upwards compatible with ANSI C and with existing C practice. This section explains the major differences.

The following complete program compiles in C but does not compile in C++. Explain why.

Foo.cpp:

int main() { return atoi("0"); }

All functions must be declared before use. Function prototypes for forward declared functions are required in C++. The prototype for atoi() has not been declared.


In C++ the following code is incorrect. Explain why.

// a.cpp:
extern int iO
int iO;

// b.cpp:
extern int iO
extern int iO
int iO//


In C++, an object can only be defined once across all translation units. At link-time the program generates a multiple definition error. The definition
int iO;

is present in both a.cpp and b.cpp. So the variable iO is defined more than once. The declaration
extern int iO;
may be present multiple times.


The following C code is incorrect. Explain why.
void f(i, j)

 int i, j; { } // error

Old style K&R function formal argument declarations are illegal in C++. Use the new ANSI C function argument declaration syntax instead.


The following complete program runs in C but does not compile in C++. Explain why.

int f(); int main() { return f(1); } // error

In C++, a function declaration with an empty parameter list declares the function to accept no arguments. (In C, it declares the function to accept unspecified arguments.)




extern void* alloc(size_t);
int* p = alloc(sizeof(*p));

C++ does not provide implicit conversions from void* to int* (or Object*) , To correct the problem issue:

int* q = (int*)alloc(sizeof(*q));

The following program compiles in C, but does not compile in C++. Explain why.
enum Colour { red, green, blue };
Colour colour = red;
colour = colour + 1;

C++ does not provide implicit conversion from int to an enum type.

To correct the problem issue:

colour = (Colour)(colour + 1);

The following code generates an error. Explain why.

// a.cpp:
typedef unsigned char BYTE;
int f(BYTE) { ... }

// b.cpp:
extern int f(char);
...
f(1);

A link time error f(char) not defined is generated.
C++ enforces typesafe linkage. The declarations and definition of a function must agree exactly in the types of parameters and return value.

The following code compiles in C but not in C++. Explain why.


struct Symbol {
struct Pos { int line, column; };
...
};
struct Pos pos; // OK in C, error in C++

C++ has properly nested types. Types declared within a structure are not exported to global scope.


Why the following code does not compile in C++:
if (j1)
goto L1; // error, jump past initialization
int ik = 1; // explicit initialization
L1:



goto L1;
jumps past initialization of the variable ik.
According to ARM r.6.7, in C++ it is illegal to jump past a declaration with an explicit or implicit initializer unless the declaration is in an inner block that is not entered (that is, completely bypassed by the transfer of control) or unless the jump is from a point where the variable has already been initialized. [Stroustrup], r.6.7.

Should the following code compile in C++? Explain.:
int j2 = 2;
if (j3)
goto L2;
{ int ik = 1; }
L2:

Yes; j2 is already init'd, and ik is in inner block

Should the following code compile in C++? Explain.:
switch (c) {
case 'd':
int nd = 1;
break;
case 'e': {
int ne = 1;
break;
}
case 'f':
break; // (but skipping 'ne' initialization is OK)
};

No. In the switch to statement skips the initialization of nd on case f. But, skipping of ne is OK, since the variable is defined within inner blocks {}.



Which of the following is valid:

class A {
private:
int a;
int Aa {return a;} // Valid [ ] Invalid [ ]
protected:
int b;
public:
int c;
int* Aa() { return &a;} // Valid [ ] Invalid [ ]
};

class B : protected A
{
private:
int Ba () { return &a};
};

class C : protected B
{

};



Which of the following is valid:

class A {
private:
int a;
int Aa {return a;} // Valid [ ] Invalid [ ]
protected:
int b;
public:
int c;
int* Aa() { return &a;} // Valid [ ] Invalid [ ]
};

class B : protected A
{
private:
int Ba () { return &a};
};

class C : protected B
{

};
}
Which of the following is valid:


The following program has a memory leak. How could you prevent the memory leak by modifying function declarations in the Base class?

class Base
{
public:
Base();
~Base();
char* pItemBase;
};

class Derived : public Base
{
public:
Derived();
~Derived();
char* pItemDerived;
};

Base::Base()
{
pItemBase = new char[5];
}

Base::~Base()
{
delete [] pItemBase;
}

Derived::Derived()
{
pItemDerived = new char[10];
}

Derived::~Derived()
{
delete pItemDerived;
}

void main()
{
Base* pBase = new Derived;
delete pBase;
// memory has leaked;
}


Eventhough pBase is pointing to an object of a derived class, a functions of the derived class will not be invoked unless the function is virtual. When issuing delete, The destructor of class D is not called and consequently pItemDerived is not erased and a memory leak occurs. To correct the problem and insure that the derived class (as well as the base class) destructor is called make the destructor for the base class virtual (consequently the destructor for the derived class is also made virtual). So, issue:

class Base
{
public:
Base();
virtual ~Base();
char* pItemBase;
};




Below, which Foo() is invoked? What is printed?


#include

class Base
{
public:
virtual void Foo();
};

class Derived : public Base
{
public:
virtual void Foo();
};

void Base::Foo()
{
cout << "Base" << endl;
}

void Derived::Foo()
{
cout << "Over " << endl;
}

void main()
{
Base* pBase = new Derived();
pBase->Foo();
delete pBase;
}


The number and the type of parameters of Derived::Foo() matches the number and the type of parameters of Base::Foo(). The two Foo() functions are said to have the same signature.
Derived::Foo() is taking advantage of the virtual mechanism. pBase is pointing to a Derived class object, which causes the Derived class version of Foo() to be invoked and the following to be printed:
Derived

In the following code, the programmer expects Derived to be printed; instead Base is being printed.? Explain why.

#include

class Base
{
public:
virtual void Foo(double) const;
};

class Derived : public Base
{
public:
virtual void Foo(int);
};

void Base::Foo(double) const
{
cout <<"Base" << endl;
}

void Derived::Foo(int)
{
cout << "Derived" << endl;
}


void main()
{
int iVar = 1;
Base* pBase = new Derived();
pBase->Foo(iVar);
}


The number and the type of parameters of Derived::Foo() does not match the number and the type of parameters of Base::Foo(). Derived::Foo() is only an overloaded version of Base::Foo() and does not take advantage of the virtual mechanism. So, eventhough pBase is pointing to a Derived class object, and the passed parameter, iVar, is of type int, the Base class version of Foo() is invoked and the following is printed:
Base

In the following code, the programmer expects Derived to be printed; instead Base is printed. Explain why.


#include

class Base
{
public:
virtual void Foo() const;
};
class Derived : public Base
{
public:
virtual void Foo();
};

void Base::Foo() const
{
cout << "Base" << endl;
}

void Derived::Foo()
{
cout << "Over " << endl;
}



void main()
{
Base* pBase = new Derived();
pBase->Foo();
}


Since Derived::Foo() is missing a const, it does not take advantage of the virtual mechanism and is only an overloaded version of Base::Foo(). The two Foo() functions are distinguishly different since the base one is not allowed and the derived one is allowed to change member variables of the class.
So, even though pBase is pointing to a Derived class object, Base::Foo() is invoked and the following is printed:
Base

What is the outcome of the following code?

#include

class A
{
public:
virtual void Foo1() {cout << "Foo1";}
};


class B : public A
{
public:
void Foo2() {cout << "Foo2;}
};


void main()
{
B bObject;
A *pA = &bObject;
B *pB = &bObject;

pA->Foo1();
pB->Foo1();
pA->Foo2();
pB->Foo2();
}

/*

Both pA and pB point to a B class object. Since Foo1() is a virtual function redefined in B, the B copy of the function is called.
pB->Foo2() calls Foo2() of class B. However, pA->Foo2(), generates a compile time error since Foo2() is only defined in class B but pA is a pointer of class type A. Even though pA is currently pointing to an object of class B it is only aware of those members of class B that are defined in class A.

Below, the programmer expects Derived::Foo() to be called twice. Instead, why is a compile-time error generated?

#include

class Base
{
public:
virtual void Foo() { cout << "base" << endl;}
};

class Derived : public Base
{
protected:
void Foo() { cout << "derived" << endl;}
};


void main()
{

Derived vfderived;
Base *pvfbase = &vfderived; // Pointer to base type.
Derived *pvfderived = &vfderived; // Pointer to derived type.

pvfbase->Foo();
pvfderived->Foo();

}

/*
The access control applied to virtual functions is determined by the type used to make the function call. Overriding declarations of the function do not affect the access control for a given type.
Above, since Foo() is virtual, both calls will attempt to call the derived version of Foo(). Since in class Base the access to Foo() is public pvfbase could successfuly call Derived::Foo() with a public access. However, in class Derived the access to Foo() is protected, pvfderived cannot call Foo() and an error should be generated at compile time.

*/


What is wrong with the following declaration of PrintID()? Correct the code by keeping PrintID() a pure function.

#include

class Car
{
public:
void PrintID() = 0;
};


class DomesticCar : public Car
{
public:
void PrintID();
};

void DomesticCar::PrintID()
{
}

void main()
{

}

The = 0in front of PrintID() makes it a pure function. But Pure functions must be virtual . To correct the problem, you must issue the following instead:

virtual void PrintID() = 0;

Below, which conversion operator is called at the line where lVar = dollar is issued?

class Symbol
{
public:
Symbol();
operator short() {return 2;}
operator int() {return 4;}
};



void main()
{
long lVar;
Symbol dollar;

lVar = dollar;

}

The int() and the short() are equal candidates for the conversion of a Symbol into long. So, an ambiguous operation is being attempted that yields a compile-time error.

Below which version of the Test() constructor is called?

class Test
{
public:
Test();
Test(int i=0);
Test(int i);
};

void main()
{
Test X;
Test Y(0);
}


Test X is illegal since it is ambiguous whether to call Text::Test() or Test::Test(int i=0). Similarly, Test Y(0) is ambigious since it is not clear whether to call Test(int i=0) or Test(int i).

**
abstract derived is ok - derived of abstract base class is abstract base class
**
What is printed in the following program:

#include

class BaseX
{
public:
BaseX();
~BaseX();
};

BaseX::BaseX()
{
cout << "BaseX Construct" << endl;
}

BaseX::~BaseX()
{
cout << "BaseX Destruct" << endl;
}

class BaseY
{
public:
BaseY();
~BaseY();
};

BaseY::BaseY()
{
cout << "BaseY Construct" << endl;
}

BaseY::~BaseY()
{
cout << "BaseY Destruct" << endl;
}

class Derived : public BaseY, BaseX
{
public:
Derived();
~Derived();
};

Derived::Derived()
{
cout << "Derived Construct" << endl;
}

Derived::~Derived()
{
cout << "Derived Destruct" << endl;
}

void main()
{
Derived One;
}

Base class constructors are called in the order in which they are specified in the class definition (unless virtual base classes are present.) Above, the Y class is specified before the X class so its constructor is called first. Futhermore, the destructors are called in the reverse order that the constructors are called. So the output is as follows:

BaseY Construct
BaseX Construct
Derived Construct
Derived Destruct
BaseX Destruct
BaseY Destruct


What is wrong with the following code? How could you correct the problem?

class Base
{
};

class Derived : public Base
{
public:
Derived();
~Derived();
private:
char *sContent;
};

Derived::Derived()
{
sContent = new char[10];
}

Derived::~Derived()
{
delete sContent;
}

void main()
{
Base* pBase = new Derived;
delete pBase;
}

There is a memory leak since the destructor of the Derived class is never called and the memory allocated for sContent is never released. The derived class destructor is not being called because the destructor is not virtual. So, the solution is to make the destructor virtual. If we make the destructor of a base class virtual, then the destructor of all its derived classes will also become virtual. So, the solution is to add a virtual destrcutor in the definition of the Base class as follows:
public:
virtual ~Base();


How many times the constructor for base1 and the constructor for base2 are called? Why?

#include

class base1
{
public:
base1() {cout <<"base1 Constructor\n";}
~base1() {cout <<"base1 Destructor\n";}
};

class base2
{
public:
base2() {cout <<"base2 Constructor\n";}
~base2() {cout <<"base2 Destructor\n";}
};

class derived1 : public base1, virtual public base2
{
public:
derived1() {cout <<"derived1 Constructor\n";}
~derived1() {cout <<"derived1 Destructor\n";}
};

class derived2 : public base1, virtual public base2
{
public:
derived2() {cout <<"derived2 Constructor\n";}
~derived2() {cout <<"derive2 Destructor\n";}
};

class last : public derived1, public derived2
{
public:
last() {cout <<"last Constructor\n";}
~last() {cout <<"last Destructor\n";}
};

void main()
{
last X;
}


The constructor for base1 is called twice (once through derived1 and another time through derived2.) Since base2 is a virtual base class, its constructor is called only once.

The output is as follows:

base2 Constructor
base1 Constructor
derived1 Constructor
base1 Constructor
derived2 Constructor
last Constructor
last Destructor
derive2 Destructor
base1 Destructor
derived1 Destructor
base1 Destructor
base2 Destructor


How many times are base0 and base1 called? What is the output?

#include

class base0
{
public:
base0() {cout << "base0" << endl;}
};

class base1 : virtual public base0
{
public:
base1() {cout << "base1" << endl;}
};

class derived0: virtual public base1, virtual public base0
{
public:
derived0() {cout << "derived0" << endl;}
};

class derived1: virtual public base0, public base1
{
public:
derived1() {cout << "derived1" << endl;}
};

class derived3 : public base1
{
public:
derived3() {cout << "derived3" << endl;}
};

class app: public derived0, derived3, virtual derived1, virtual public base0
{
public:
app() {cout << "app" << endl;}
};

void main()
{
app myapp;
}

Since base0 is always virtual, it is called only once. base1 is called called twice.
The output is as follows
****
base0, the virtual base class highest in the hierarchy, is called first. Since base0 is always virtual its constructor is called only once. Next, to construct derived1, base1() and then derived1() are called. base1() is called one more time to construct derived0 and then derived0() is called. Finally, app() is called. Note that base1() is used both as a virtual and non-virtual base class. So, it is called once for all virtual instances and non-virtual instance.
derived1 is listed first so it comes first. ***
/*
base0
base1
base1
derived1
derived0
base1
derived3
app
*/

Given:

#include

class X
{
public:
X();
X(int);
X(double);
X(const X&);
X& operator = (X&);
};


Which constructor and operator is invoked below:

void main()
{
X a;
X b(1);
X c(1.0);
X d(c);
X e = c;
b = c;
}

X a // invokes the default constructor X().
X b(1) // invokes X(int).
Xc(1.0) // invokes X(double).
X d(c) invokes the copy constructor X(const X&).
X e =c also invokes the copy constructor X(const X&).
b = c invokes the asignment operator X& operator = (X&).


Given:

class A
{
};

class B
{
public:
B(int);
};

class C
{
public:
C();
C(const C&);
};

class D
{
private:
D();
};

Explain why each line in main() is legal or illegal.

void main()
{
A a;
A a1 = a;

B b;
B b1(1.2);
B b2(b1);

C c;

D d;
}

A a; // is legal since the compiler supplied default constructor could be used.
A a1 = a; // is legal since the compiler supplied copy constructor could be used.

B b; // is illegal since a non-default constructor is supplied but a default constructor (a constructor taking no arguments) is not supplied. In this case, since another constructor is already defined, no default constructor will be provided by the compiler. So, the compiler will not supply a default constructor when another constructor has been defined for a class.
B b1(1.2); // is legal since B::B(int) could be used.
B b2(b1); // is legal since the compiler-supplied copy constructor still could be used.

C c; // is legal since along with the non-default constructor a default constructor (C()) is being supplied.

D d; // is illegal since the default constructor is made private.



Given:
class A
{
};

class B
{
public:
B(int);
};

class C
{
public:
C();
C(const C&);
};

class D
{
private:
D();
};

Which of the following member variables are illegal?

class app
{
A a;

B b;

C c;

D d;
};

Similar to exercise constrct0.cpp class B and class D do not have appropriate default constructors and thus B b; and D d; are illegal.


Below, what are the final values for a and b?

#include

class base
{
public:
base(int i) : a(i) {}
int a;
};

class derived : public base
{
public:
derived() : b(1), base(b+1) {}
int b;
};

void main()
{
derived d;
cout << d.a << endl;
cout << d.b << endl;

}


In the constructor for the derived class, base(b+1) passes derived::b to the base class constructor.
However, the members of the derived class are not initialized yet (base must be initialized first!) Thus, derived::b is undefined and thus base(b+1) gets an undefined or random value. So the base class constructor uses the undefined value to initialize member base::a (throught the a(i) statement). Thus an
undefined value is assigned to base::a.
Next, derived::b is initialized with 1.
Given the following declarations:
class base {};
class derived1 : base {};
class derived2 : private base {};
class derived3 : protected base {};

derived0 d0;
derived1 d1;
derived2 d2;
derived3 d3;
base* pbase;

Which of the following assignments are illegal?

pbase = &d1;
pbase = &d2;
pbase = &d3;

All the assignments are illegal. None of the derived classes have derived publicly from base. So, none of them are of type base which means that a base* cannot point to them.
In the following program, how many times will the destructor WinDestruct::~WinDestruct() be called? What is printed?

#include
#include


class WinDestruct
{
public:
WinDestruct(int i);
~WinDestruct();
private:
int id;
};

WinDestruct::WinDestruct(int i)
{
id = i;
}

WinDestruct::~WinDestruct()
{
cout << "Destruct " << id;
}

WinDestruct globalX(100);
void main()
{
WinDestruct Localx(200);

exit(0);
}


When exit() is called, destructors for local variables in the current scope are not called. However, global variables are destroyed in their normal order. So, only the destructor for globalX is called and the output is:

Destruct 100
The following code has a serious bug. What is the bug?

#include
#include

class CStr
{
public:
CStr() {pszString = NULL;}
CStr(const char * pszInitial);
CStr::~CStr();

char* GetData() {return pszString;}
private:
char* pszString;
};

CStr::CStr(const char* pszInitial)
{
if (pszInitial!=NULL)
{
pszString = new char[strlen(pszInitial)+1];
strcpy(pszString, pszInitial);
}
else
{
pszString = NULL;
}
}

CStr::~CStr()
{
if (pszString) delete [] pszString;
}

void passString(CStr newStr);
void passString(CStr newStr) {}

void main()
{
CStr original("hi");


passString(original);

}

After the passString(original) call, the content of the pszString member variable is lost. The parameter in passString() is passed by value. The compiler-generated copy constructor is called to make a copy of the passed object. The default copy constructor only makes a shallow copy which means that that pointer member variables inside the new object and the original object are identical. Another words, char * pszString of the two objects are the same. When the function terminates the new copy needs to be destroyed by the compiler. This means that the char* pszString of the original object is also destroyed.
One remedy is to pass the arguments by reference. So, the passString declaration could be as follows: passString(CString& passStr);
what is wrong with the following implementation of the + operator?
(Hint: In function main(), determine which usage fails.)

class complex {
public:
complex(double rr=0, double ii=0): r(rr), i(ii) {}

complex operator +(const complex& rhs);

double getr() {return r;}
double geti() {return i;}
private:
double r, i;

};

complex complex::operator+(const complex& rhs)
{
return complex(r+rhs.r, i+rhs.i);
};

void main()
{
complex c1(10,10);
c1 = c1 + 2;
c1 = 2 + c1;
}

The operation (c1+2) works fine. The const complex& rhs parameter refers to the right-hand side operand. When c1 = c1 + 2 is issued the right-hand side value is 2 and it is passed to the complex& rhs operator of the + operator. Then the compiler invokes the constructor Complex(double rr=0, double ii=0) to issue a call such as Complex(2) which results in a Complex object being passed.

The operation (2 + c1) fails. The c1 on the right-hand side is already a Complex object and thats what we want. However, the 2 on the left hand side is not a Complex object and will not be converted to a complex object. The left-hand side operand is assumed to be the object that is issuing the function call and thus it must be a complex object before hand. One way to correct the problem is to declare the + operator as a friend operator taking two parameters. In such a case the Complex() constructor could be called for the left-hand side operand as well.

so declare the following:
public:
friend complex operator +(const complex& lhs, const complex& rhs);

And define as follows:
complex operator +(const complex& lhs, const complex& rhs)
{
return complex(lhs.r+rhs.r, lhs.i+rhs.i);
}
1)why must return a whole new object: return complex()
2) chri*.cpp files for pointer to members
What is wrong with the following code?

const int j = 5;

int *p = (int *) &j
p++;

By declaring j as const, j was meant to retain its value throughout the application. But unfortunately, by issuing (int *) someone has casted-away the constness of j and inadvertently modified its value through p++.

Below, the programmer intended the value of derived::getID() to be printed, but
instead base::getID() got printed. Explain why. Correct the function get() to invoke
the correct getID() regardless of whether a derived or a base object is passed:


#include

class base
{
public:
virtual int getID() const { return 1;}
};

class derived : public base
{
public:
virtual int getID() const { return 2;}
};

int get(base);
int get(base obase)
{
return obase.getID();
}

void main()
{
derived d;
cout << get(d) << endl;
}

The virtual mechanism is not beign used effectively since the get() function recieves its base parameter by value and after copying the derived class information is lost. In effect, a copy of the passed derived object is made but only bases portion of the object is used. One solution is to avoid copying and receive parameters by reference instead:
int get(const base& obase);


//Given the following classes:

class base
{
public:
virtual void myFunc(int);
virtual void myFunc(int, int);
};

void base::myFunc(int)
{}

void base::myFunc(int, int)
{}


class derived : public base
{
public:
void myFunc(int, int);
};

void derived::myFunc(int, int)
{}

// why the following code fails to execute?
void main()
{
derived d;
d.myFunc(1);
base *b = &d;
b->myFunc(1);
}


Any declaration of a member in a derived class hides all members with the same name in the base class, regardless of argument types. In the above code, derived::myFunc(int, int) hides base::myFunc(int). So, d.myFunc(1) fails. To correct the problem, you should specify any hidden functions in the derived class.
So in the derived class you could also issue:
void myFunc(int i) {Base::myFunc(i);}
Also, since base::MyFunc() is virtual, you could without any change to the above code, get to the base::myFunc(1) through pointers (which profoundly utilize the virtual mechanism) and successfuly execute b->myFunc(1).


Below, which f() function is invoked:

class OverLoad
{
public:
void f(double i) {cout << i;}
private:
void f(int i) {cout << i;}
};

void main()
{
OverLoad X;
X.f(1);
}


The best match for X.f(1) is f(int i). However, f(int i) is private and inaccessable. Nevertheless, the compiler will attempt to use it and a compile-time error at X.f(1) line is generated.


Below, which version of f() is invoked?



#include

class Base
{
public:
virtual void F(int A) { i = A;}
virtual void F(int A, int B) {i = A+B;}

protected:
int i;
};

class Derived : public Base
{
virtual void F(int A, int B) { i = A+B+1;}
};

void main()
{
Base* X;
Derived Y;

X = &Y;
X->F(1);
X->F(1, 2);
}


X->F(1) calls Base::F(int A) even though X points to an object
of type Derived. The reason is that the version of F() in Derived
does not take one parameter and thus it does not overwrite the version of
F() in Base which takes one parameter.
The compiler is forced to call
the version of the F() function that takes only one parameter and that
version is only available in Base.

X->F(1, 2) calls F(int A, int B) in Derived since X points to an
object of type Derived and F(int A, int B) is declared virtual in
Base and is overwritten in Derived. Note that since F(int A, int B)
is declared virtual in Base, it is implicitly virtual in Derived.

Given the followin class definition:

#include

class String
{
public:
String();
String(const char* pszInitial);
~String();
private:
char* pszString;
int len;
};

String::String()
{
pszString = 0;
len = 0;
}

String::String(const char* pszInitial)
{
if (pszInitial!= 0)
{
len = strlen(pszInitial);
pszString = new char[len+1];
strcpy(pszString, pszInitial);
}
else
{
len = 0;
pszString = 0;
}
}

String::~String()
{delete [] pszString;}

What is wrong with the following assignment?

void main()
{
String s1("hello");
String s2;

s2 = s1;
}

Using the compiler-supplied assignment operator (=) the pszString member variable of both the s1 and s2 object will point to the same location. When the function terminates, the objects need to be destroyed. That means you have arranged for the same pszString to be destoyed twice.
The remedy is to supply your own assignment operator (=) that allocates new memory for a new pszString. Additionally, you might also want to supply your own copy constructor to avoid a similar problem when when the copy constructor is invoked to copy one object to another (during passing of parameters by value and in code such as String s2(s1)):

class String
{
public:
String();
String(const String& source);
String(const char* pszInitial);
~String();
String& operator=(const String& source);
private:
char* pszString;
int len;
};

String& String::operator=(const String& source)
{
if (source.pszString == pszString)
return *this;

delete pszString;
if (source.pszString != 0)
{
len = strlen(source.pszString);
pszString = new char[len+1];
strcpy(pszString, source.pszString);
}
else
{
len = 0;
pszString = 0;
}
return *this;
}


String::String(const String& source)
{
if (source.pszString != 0)
{
len = strlen(source.pszString);
pszString = new char[len+1];
strcpy(pszString, source.pszString);
}
else
{
len = 0;
pszString = 0;
}
}

In the following code, the compiler does not allow the class bottle to contain a member variable of the class liquid. Implement constructor(s) differently to correct the problem.

class liquid
{
public:
liquid(int i) {type = i;}
private:
int type;
};

class bottle
{
public:
bottle(int i) {}
liquid content;
};

void main()
{
bottle X(1);
}

A class may be a member variable of another class if any of the following holds true:
1) The contained object's class requires no constructor.
2) The contained object's class has an accessible default constructor.
3) The containing class's constructors all explicitly initialize the contained object.


Since a member objects (liquid) requires a constructor and no default constructor is available, the constructor for the class must initialize its member object. So, the constructor for bottle should be written as:

bottle(int i): content(i) {}

In the following code, which invocation of the getState() function is legal? why?


class VFuncBase
{
protected:
virtual int getState() { return _state; }
int _state;
};

class VFuncDerived : public VFuncBase
{
public:
int getState() { return _state; }
};

void main()
{

VFuncDerived vfd; // Object of derived type.
VFuncBase *pvfb = &vfd; // Pointer to base type.
VFuncDerived *pvfd = &vfd; // Pointer to derived type.
int State;

State = pvfb->getState();
State = pvfd->getState();
}


The access control applied to virtual functions is determined by the type used to make the
function call. Overriding declarations of the function do not affect the access control for a given
type.
In the preceding example, calling the virtual function getState using a pointer to type
VFuncDerived calls VFuncDerived::getState, and getState is treated as public. So, State = pvfd->getState() is legal.
However, calling getState using a pointer to type VFuncBase is an access-control violation even though the Derived version of getState which is public (and accessable) should be invoked. The bottom line is that our pointer pvfb is of type VFuncBase* and there getState is declared private.

Given the following classes:
class base
{};

class derived1 : public base
{};

class derived2 : public base
{};

class final : public derived1, public derived2
{};

What is wrong with the following code?:

final obj;
base* pbase;
pbase = &obj;

The conversion to type base* is ambiguous because the compiler does not know which subobject of type base to use. To correct the code you could explicitly specify which subobject you mean to use, as follows:
(base *)(derived1 *)&d // Use derived1 subobject.
or
(base *)(derived2 *)&d // Use derived2 subobject.

The constructor must be accessible before the compiler can perform these steps. Even though
the compiler can eliminate the temporary creation and copy steps in most cases, an inaccessible
copy constructor
causes equal-sign initialization to fail. Consider the following example:

Given the following class:

class anInt
{
anInt( const anInt& ); // copy constructor.
public:
anInt( int ); // int constructor.
};

Could you execute the following line?
anInt myInt1 = 7

what about this line?
anInt myInt2( 7 );

When issued outside the anInt class, anInt myInt1 = 7, yields an access-control violation. The reason is that the copy constructor anInt( const anInt& ) is needed to construct myInt1 but the constructor is made private and inaccessable.

anInt myInt2(7) is fine since it could successfuly invokes the int public construcutor.

Identify the ambiguity in the following code:

class Money
{
public:
// constructor accepting a long
Money( long l ) { dollar = l; }

// conversion operator to type long
operator long() { return dollar; }

int operator>=( const Money &m )
{ return dollar == m.dollar;}
private:
long dollar;
};

int foo()
{
Money m(100);
long num = 1;

return m >= num;
}

In the expression m >= num, the compiler has two choices neither of which is more correct:
1) It can either convert m to a long using the long() operator and then compare two long values.
2) It can convert num to Money using the constructor and then compare two Money objects using the user-defined operator==.
To avoid a compile-time error, you may guide the compiler by doing one of the conversions yourelf as follows:

return m.operator long() >= num;

or using the constructor:

return m >= Money(num);

Below, which version(s) of Options() and Strict() is invoked? What is the
output?

#include

class Base
{
public:
virtual ~Base() {}
virtual void Options(int i);
virtual void Strict(int i);

};

void Base::Options(int i)
{
cout << "Base Options" << endl;
}

void Base::Strict(int i)
{
cout << "Base Strict" << endl;
}

class Derived : public Base
{
public:
void Options(int i, int j=0);
void Strict(int i);
};

void Derived::Options(int i, int j)
{
cout <<"Derived Options" << endl;
}

void Derived::Strict(int i)
{
cout << "Derived strict" << endl;
}

void main()
{
Derived X;
Base *Y = new Derived;

X.Options(1);
Y->Options(1);

X.Strict(1);
Y->Strict(1);

delete Y;
}


Eventhough the additional parameter declared in the derived class has a default value, the number of parameters in the derived class are not considered to match the number of parameters in the base class.
Options() is not overwritten by the derived class (its simply another overloaded function.) Since the options() which is defined in Derived is not copied to Y, Y->Options(1) points to the copy of the function
which is defined in the base class. The function Strict(), however, is overwritten in the derived class and thus Y recieves a copy of the function that is defined in the derived class.
So, the output is:

Derived Options
Base Options
Derived strict
Derived strict
How many times will the following loop execute?

for (int i = 0; i < 5, i < 10; i++)
cout << i;

The comma opertor returns the result of the expression to its right. So,
i < 10 is the condition that terminates the loop and the llop executes 10
times.

Below, which of the asignments in the set() function are illegal:


class test
{
public:
void set(test* that);
private:
int i;
};


void test::set(test* that)
{
this->i = i;
that->i = i;
this = that;
}


void main()
{
test x;
test* y = new test;
x.set(y);
delete y;

}

this = that is the only illegal assignment. Since the this pointer is a const it is non-modifiable. Also, the assignment this->i = i; does not make sense since this->i is the same as i.



Below, which i is used by the function set():


int i = 1;

class test
{
public:
int i;
public:
static void set();
};


void test::set()
{
i = 2;
}

void main()
{
test x;
x.set();
}


Niether! A compiler error is generated. The set() function is static so it does have access to non-static member variables of the class. The external variable I could be accessed via the scope resolution operator (::) as follows:
:: i = 2;


why the following program does not run? Correct the problem.

class test
{
public:
static void set() {counter=1;}
static int counter;
};

void main()
{
test x;
x.set();
}


The static function set() could access static members. However, counter must be defined outside the class declaration. To correct the problem, add the following line after the declaration of class test.

int test::counter;

What is wrong with the following implementation of the = operator:

class Str
{
public:
Str& operator=
(const Str&);
private:
char* content;
};

Str& Str::operator=(const Str& s)
{
delete [] content;
content = new char[strlen(s)+1];
strcpy(content, s.content);
return *this;
}


The = operator should check for assignment to self. One way to do so is as follows:

Str& Str::operator=(const Str& s)
{
if (this != &s)
delete [] content;
content = new char[strlen(s)+1];
strcpy(content, s.content);
}
return *this;
}



/*
Below, which assignments are illegal?

class Point
{
int Location;
};

class Circle : public Point
{
int Radius;
};

void main()
{
Point aPoint;
Point *paPoint;
Circle aCircle;
Circle *paCircle;

// Assignments:
aPoint = aCircle;
aCircle = aPoint;
paPoint = &aCircle;
paCircle = &aPoint;
}


aCircle = aPoint; and paCircle = &aPoint are illegal. You cannot assign an
object of a base class to an object of the derived class.
The base class
object does not have all the members of the derived class object. Therefore,
some of the members of the derived class will be undefined.

In the code above, when you issue aCircle = aPoint, aCircle expects to have
a Radius copied to it, but aPoint does not have a radius.

Conversly, when you issue aPoint = aCircle, aCircle has all the members of
aPoint and thus all members of aPoint are defined after the assignment.

Which Show() function is invoked in the following program?

#include

class Base
{
public:
virtual void Show() {cout << "Base" << endl;}
};

class Derived : public Base
{
public:
void Show() {cout << "Derived" << endl;}
};

void ShowValue(Base X)
{
X.Show();
}

void ShowPointer(Base *X)
{
X->Show();
}

void ShowReference(Base &X)
{
X.Show();
}

void main()
{
Derived X;

ShowValue(X);
ShowPointer(&X);
ShowReference(X);
}


Output:

Show() is defined virtual in the base class and in all cases X is an object
of the derived class. But, only in the calls to ShowPointer() and
ShowReference() the version of Show() belonging to the derived class is
invoked.
For polymorphism or the virtual function
mechanism to work, you must either use pointers or reference parameters.

Thus the output is:

Base
Derived
Derived


#include
Below, why is i not initialized to 2 (or j+1)?


class test
{
public:
test();
void dum();
private:
int i;
int j;
};

test::test():j(1), i(j+1)
{
}


void test::dump()
{
cout << "i: ", i << endl;
cout << "j: ", j << endl;
}

void main()
{
test x;
x.dump();
}

The order in which the member initializers are specified in the constructor does not affect the order in which the members are constructed. The members are constructed in the order they are declared in the class. so to initialize j before i, change the order of declaration as shown:

private:
int j;
int i;



/*
What is wrong with the following function definition?



void test(s)
char *s
{
}


C++ requires that the function definition declare the types of all parameters within the parameter list. To correct the problem you must conform to the new style as follows:

void test(char *s)
{
}

Which of the following assignments are illegal?

void main()
{
char bufferA[5], bufferB[5], bufferC[5];

char *const ptrA = bufferA;
*ptrA = 'a';
ptrA = bufferB;

const char *ptrB = bufferC;
ptrB = bufferA;
*ptrB = 'a';
}


So, the line ptrA = bufferB is illegal since you cannot change a const pointer. Also, the line *ptrB = 'a' is illegal since ptrB is a pointer to constant character and you cannot change the char that ptrB points to.
(Note: char *const is read as const pointer to character. In the same manner, const char * is read as pointer to character constant or pointer to constant character.)


Why doesnt the following chained assignment work:

class assign
{
public:
assign(int x) {i = x;}
assign(const assign &other);
assign& operator= (const assign &other); // return a pointer to self
private:
int i;
};

assign::assign(const assign &other)
{
i = other.i;
}

assign &assign::operator=(const assign &other)
{
i = other.i;
}

void main()
{
assign X(1);
assign Y(2);

X = Y;

assign Z = X;

X = Y = Z; // chained assignments
}

To allow chained assignments such as X = Y = Z, the assignment operator must
return *this
. so revise as follows:

assign &assign::operator=(const assign &other)
{
i = other.i;
return *this; // return a pointer to self to support chained assignments
}


The programmer expects a value of 3 to be printed. Why the code fails?

#include
class Grand
{
public:
Grand(int i) {m_i = i;}
int geti() {return m_i;}
protected:
int m_i;
};

class Parent : virtual public Grand
{
public:
Parent(int j) : Grand(j) {}
};

class Child : public Parent
{
public:
Child(int k) : Parent(k) {}
};

void main()
{
Child c(3);
cout << c.geti();
}

A derived class should initialize a virtual base class in its initializer
list unless the virtual base class has a default constructor or a constructor
that takes no arguments.


In the above code, the Child class is incorrectly expecting the m_i variable of the Grand class to be initialized through the Parent class constructor. To correct the problem, abide to the rule stated above and arrange for the Child class constructor to call the Grand class constructor as follows:
Child(int k) : Grand(k), Parent(k) {}


Below, could t1 and t2 be created how about t3 and t4?


class Test
{
public:
friend void util();
private:
Test(){}
Test(int) {}
};


void util()
{
Test t3(1);
Test t4;
}

void main()
{
util();
Test t1(1);
Test t2;
}


A class with all private or all protected constructors is known as a private class. Only a friend class or function could instansiate a private class. So, only t3 and t4 could be instansiated.

What is wrong with the following code:
class B
{
};

class D : protected B
{
};

void f(B* pB);

D* pD = new D;
f(pD);
delete pD;


A derived class pointer could be implicitly converted to a base class pointer only by a function that can access that class. If the derived class derives publicly from the base class then every function could do the conversion. However, if the derivation is private, only friend functions or member functions of a derived class which have the base as the immediate base class could do the conversion. If the derivation is protected, only friend functions or member functions of a derived class which have the base as a base class could do the conversion.

Why is the following code incorrect?


class Test
{
public:
Test(int x);
const int i;
};


Test::Test(int x)
{
i = x;
}

void main()
{
Test X(1);
}


Data members that are references or const must be initialized through member initialization list. In the above code, the const member i is not being initialized through member initialization list. To correct the problem, change the constructor to:

Test::Test(int x) : i(x)
{
}

Are the following overloading of the f() function legal?

class X
{
void f(int x);
void f(int& x );
};

The argument lists are not sufficiently different to be unambiguously distinguished. So, f(int x) and f(int& x ) cannot be defined in the same scope.


In the following program, is the assignment x.f() = 1 legal? What is the output?

#include

class X
{
public:
X();
int & f();
private:
int iVal;
};

X::X()
{
iVal = 0;
}


int & X::f()
{
return iVal;
}

void main()
{
X x;
x.f() = 1;
int j = x.f();
cout << j << endl;
cout << x.f() << endl;
}

A function, such as X::f() above, returning a reference could be used as both an lvalue and an rvalue. Another words, it could be placed as both the left hand side and the right hand side of the = sign. So f() = 1 is legal and it assigns the value of 1 to its return value iVal. The output is:
1
1


A C/C++ programmer expected the following code to compile. What has gone wrong?

enum color {RED, GREEN, BLUE};
enum color c = 0;

In C, enumerations are integral types. Although the ARM states that enumerations are integral types in C++, it is currently accepted that enumerations are not integral, but they can be promoted to signed and unsigned int. So the line
enum color c = 0;
is illegal. Note, however, that the line
int i = RED;
is legal. The RED enum could be promoted to an int.

What will the assignment in function foo() below do?

class base
{
public:
void operator=(int i);
protected:
int j;
};

void base::operator=(int i)
{
j = i;
}

class derived : public base
{
private:
int k;
};

void foo()
{
derived d;
d = 0;
}

The code will not compile. The = is special in that it cannot be inherited. So, no operator=(int i) is available for class derived and d = 0 is illegal.

What is the result of the following substractions?:

int a[5], b[5];
int i = &a[5] - &a[1]; // (1)
int j = &a[1] - &b[1]; // (2)

Substraction of pointers is defined only when pointers point to elements of the same array.
Thus, (1) yields a value of 4 and (2) is illegal.


What is the value of the parameter that is passed in the following function call:

int i;
f((i=3, j=i+1));

The operators ,, && and || guarantee that their left-hand operand is evaluated before their right-hand operand. So i = 3; is guaranteed to take place first and after the assignments I would equal 3 and j would equal 4. Also, the , operator returns the result of the expression to its right which here is the same as the value of j. So, a value of 4 is passed in the function call.

What is the outcome of the following code:

char s[] = \XCA;
cout << s;

Below, what is the final value of j?:

int j = 0;
j += j++;

If a value is modified twice in an expression, the result of the expression is undefined except when an ordering is guaranteed by the operators involved. So, above, the value of j is uncertain.

What is wrong with the following code:

class X {
public:
inline void f();
};

void main()
{
X x;
x.f();
}

inline void X::f()
{
}

An inline function cannot be used before it is defined.

Below, what is the final value of a and b?

static int a;
int b = a;
a++;

Since a is static, it is initialized to a value of 0; So b = a will assign a value of 0 to b. a++ increments a by one. So, at the end, a would equal 1 and b would equal 0.

union init.

What is wrong with the following code:

char s[4] = abcd;

The initialization does not account for the trailing \0 character. The initialization should have been:
char s[5] = abcd;

What is wrong with the following code?:

char source[] = abcd;
char* dest = new char[strlen(source)];
strcpy(dest, source);

The space allocated for dest does not take into account the \0 at the end of source. The correct way is:
char* dest = new char[strlen(source)+1];

Why the Complex + operator is not a friend => left and right hand of the + sign.

leak in + ++ when return & to new().



Why does the C++ compiler detect an error in the following code?:
char *s = abc;
void* p;
p = s;
s = p;

In C++, unlike ANSI C, a void* cannot be assigned to a pointer of a different type without an explicit cast. So s = p; is illegal. In C this was allowed to lift the burden of casting the result of malloc(). In C++ operator new is used which does not require a cast.


what is wrong with the following code? Correct it so that it will compile:

void * pv;
char * pc;
int* pi;

pv = (1) ? pc: pi;

Use of pointers to different types in the same expression is not legal. So, you may revise as follows:

if (1)
pv = pc;
else
pv = pi;

what is wrong with the following code?:

void * pv;
void * pv2;
int* pi;

pv = (1) ? pv2: pi;

This is different from the previous item. There is a standard conversion from any pointer to void*. so pi will be implicitly converted to void* and the code is fine.

What is wrong with the following code:

class B
{
public:
virtual void f(int = 3);
};

class D : public B
{
public:
void f(int = 3);
};

According to ARM: a default argument cannot be redefined by a later declaration (not even to the same value.) So, correct as follows:

class D : public B
{
public:
void f(int);
};


class B
{
};

class D : public B
{
int i;
};

D v[5];
B* pb;
pb = v;
D v2;
v2 = pb[2];
v2 = v[2];

Here pb is a B* which points to objects of type D*. Bince sizeof(B) < sizeof(D) the offset calculations are wrong and pb[n] would most likely point into the middle of some D object.

What is the value of I after the following loop executes?:

unsigned int n = 0;
int i;
for (i = -5; i < n; I++)

Conversion to unsigned happens at i < n and the loop runs forever.

Which f() is executed in the following code:

class B
{
public:
virtual void f(int);
};

class D : public B
{
public:
void f(double);
};

const int n = 1;
D obj;
obj.f(n);

Eventhough n is an int and thus f(int) provides an exact match, the declaration of f(double) hides all occurences of f() from the base class. Thus f(int) is hidden for class D, and f(double) is invoked. To unhide f(int) you may do the following:

class D : public B
{
public:
void f(double);
void f(int);
};

void D::f(int j)
{
B::f(j);
}

So, all the functions in a given set of overloaded function must be declared in the same scope.
 

Which f() is invoked in the following code?:

class A
{
f(int n);
f(int& n);
};

int j;
f(j);

An error is generated since the signature for f(int n) and f(int & n) are not sufficiently different and the two functions cannot be distinguished.
At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value.
iven the following:
class B
{
public:
virtual void vf();
static j;
enum {k};
};

class X : public B {};
class Y : public B {};
class Z : public X, public Y {};
void f(B*);
Identify and resolve all ambigious code:

Z * pZ = new Z;
B* pB1 = pZ; // ambigious: B part of X or B part of Y?
B* pB2 = (B*) pZ; // still ambigious: which B?
f(pZ); // ambigious
f((X*) pZ); // Not ambigious: B part of X
pZ->vf(); // ambigious: vf() of X or Y?
pZ->j; // Not ambigious: j is static => one occurrence only
pZ->k // Not ambigious: k is enum;
Y * pY = &Z; // Not ambigious: there is only one Y sub-object.

To disambiguate declare appropriate casts or declare as virtual as shown:

class Z : virtual public X, virtual public Y {};

Below, which f() is invoked?:

class B
{
public:
virtual void f(double);
};

class D : public B
{
public:
virtual void f(int);
};

B* pB;
D d;
pB = &d;
pB->f(1);

Normally, you would expect D::f() to be called since pB points to a D object. However, here B::f() is called. The two f() functions have different parameters and are not related to each other. That is D::f(int) is not a virtual override of B::f(double). In order for the derived class to work properly, a virtual function in a derived class must posses the same number and type of parameters as its base class.
Given:
class B
{
public:
virtual void vf();
};

class D : public B
{
public:
virtual void vf();
};
void g1(B tb)
{
tb.vf();
}

void g2(B& tb)
{
tb.vf();
}

void g3(B& tb)
{
tb->vf();
}

D d;
B b;
B* pb;
b = d;
pb = &d;

Which vf() is invoked at each of the following marked lines:

b.vf(); // mark 1
pb->vf() // mark 2
g1(d); // mark 3
g2(d); // mark 4
g3(&d); // mark 5

1) Eventhough b = d was issued, since when a copy is made, the copy is typed as a B object.
2) Since we are dealing with pointers, the virtual mechanism works properly and D::vf() is invoked.
3) B::vf() is invoked since the object is typed as a B.
4) Since we are dealing with references, the virtual mechanism works properly and D::vf() is invoked.
5) Since we are dealing with pointers, the virtual mechanism works properly and D::vf() is invoked.


So, in order for the virtual mechanism to work and members of the derived class to be invoked you must deal either with references or pointers.


What is the value of j after the following code executes?:

int j = 0;
j += j++;

j is not guaranteed to be at any specified value. As noted in ARM (r.5): if a value is modified twice in an expression, the result of the expression is undefined except when an ordering is guaranteed by the operators involved.
What value is passed to function f() below?:

f(int I);
f(i = 3, j = I + 1);

The operators
, && ||
guarantee that their left_hand operand is evaluated before their right-hand operand. Moreover, the , operand returns the result of the expression to the right. So, j would equal to 4 at the end of the evaluation and a value of 4 is passed.
What is the value of I, and j after the following code executes?:

int a[5]; b[5];
int I = &a[3] - &a[1];
int j = &a[1] - &b[1];

I would equal 2 and j is undefined since substraction of pointers is defined only when pointers point to elements of the same array.

Which of the following marked lines are illegal?:

class A
{
public:
inline void x();
void y();
void z();
};

void callz(A&);

void main()
{
A a;
a.x(); // mark1
a.y(); // mark2
callz();
}

inline void A::x()
{
}

inline void A::y()
{
}

inline void A::z()
{
}

void callz(A& a)
{
a.z(); // mark3
}

Only mark2 is illegal since an inline function cannot be called before it is defined as inline. At mark1 and mark3 A::x() and A::z() are known to be inline.

Given:
f(int);
f(int ...);
f(int, int);
f(int, char);

Which f() is called in each line below?:

1) f(1);
2) f(1,1);
3) f(1, c);
4) f(1,1,1,);

1) Ambigious: f(int) or f(int ...).
2) not ambig
3) not ambig
4) f(int ...);



The statement
B* pb = &d;
assigns the address of d to pb. So, pb has static type B but dynamic type D. Thus, a non-virtual member function call applied to *pb selects a member function from class B, but a virtual function call applied to *pb selects from D.

1) str3 = str1 + str2;
2) str1 = str2 + 1;
3) str1 = 1 + str2;

In 1 and 2 the operator + can be a member of the class. In the third case, you must define the operator as a member function, since you cannot add it to the built in int class.
So the operator should be defined as follows:
String operator+(String str1, String str2);
d3 = d2 - d1;

Since the = operator cannot be inherited and a derived class can be converted to a base class, the compiler will attempt to use the base class - operator. But, the - operator returns a base type and dObject = bObject is not allowed (since a base object is not a derived object (but the reverse is true).) To solve the problem declare an = operator that as follows:

const derived& operator = (const base&);

The elements of a const array are themselves const objects. Thus given
const char bame[] = hello;
an assignmnet such as
name[0] = j;
is an error because it tries to alter the value of name[0]. which is an object of type const char.


// Leak for not having a  virtual destructor
class B class D : public B
{ {
public: public:
B(); D();
~B(); ~D();
private: private:
char* pc1; char* pc2;
}; };

B::B() D::D()
{ {
pc1 = new char[10]; pc2 = new char[10];
} }

B:~B() D:~D()
{ {
delete [] pc1; delete [] pc2;
} }

class D : public B
{
public:
D();
~D();
private:
char* pc2;
};

D::D()
{
pc2 = new char[10];
}

D:~D()
{
delete [] pc2;
}

void main()
{
B* pb = new D;
delete pb; // leaks
}

// *****************************
/*

Given:

*/
class B
{
};

class D : protected B
{
void fMember();
}

D d;

Is the following correct?

B* pB = &d;

No. Private and protected derivation do not yield is-a. Another words in the global scope class D in not seen as a kind of class B. Therefore, pB cannot point to &d.

Is the following correct?:

D::fMember()
{
D d;
B* pB = &d;
}

Yes. B is a protected base of D and fMember is
a member of D.

// ***********************************
Below, what will pc point to?

char* pc = new (char *) [n];

The code compiles but pc will point to garbage. One new char* is
created and the code is equivilant to:
char** temp = new (char*);
char* pc = temp[n];



************


Given:

class B
{
public:
virtual f(int);
};

class D : public B;
{
public:
virtual f(double);
};

B* pb = &d;

Which f() is called below:

pb->f(1);

calls D::f(double) since pb is pointing to a D.
// ************************
Given:

class B
{
public:
B(int);
operator = ();
};

class D : public B
{
};

Which of the following is incorrect?:

B b = 1; // OK
D d = 1; // OK
b = 1; // OK
d = 1; // not OK ()

The assignment:
d = 1;
is incorrect since the = operator is not inherited.

All others are correct:


**************************
Given:
char c;
enum {begin = 'A', end = 'Z'}

Is the following assignment legal in C++:

c = begin;

It is legal, but note that begin first promotes to an int since there is no direct conversion from an enum to a char.





***************
// C users journal May 95 p99
= and copy when pointers
by value and by reference virtual function call
private and protected derivations do not yield is-a

px = py3 // error protected

y::f()
{
px = py3 // fine (protected but member function)
};
will not cause an infinite loop:

try
{

}
catch (input-overflow) {
throw input-overflow();
}


The destructor of an abstract base class must be virtual
***
The following code produced a serious runtime error. Correct the problem.

new ia int(10); // error
ia[1] = 1;

ia is not an array of integers. When assigning a value to ia[1] you might be writing to an unallocated area in memory.

You declare an array of integers as follows:

new ia int[10]; // correct
***
free wnd alloc
malloc and delete
**
What is wrong with each of the following:

int i1 = 5;
int & r1;

The initializer for r1 is missing. Reference variables (is the name ref var ok) must be initialized at the time of declaration.

extern int& r;
This is OK since an extern preceds int &r. The reference r is initialized elsewhere.

**
double &rd2 = 1;
A type mismatch is generated because rd2 is not a const.

const double &rd2 = 1;
This is OK. Rd2 is a const.

Int rd = 1;
const double &rd3 = rd;
A type mismatch is generated since rd3 is a const referencing the non-const rd. (I think) type mismatch.
**
arm 305, arm 73, 585
**
What is wrong with the following code:

int rd = 1;
int &rd2 = rd;
rd2 = rd;

A reference cannot be changed to refer to another object after initialization. The assignment:
rd2 = rd is wrong.

**

Given the following class:

class XClass
{
static char *szCaption;
char *szContent;

};

which of the following declarations is incorrect?:


// Declare a pointer to the data member
char * XClass::* pwCaption = &XClass::szCaption;
char * XClass::* pwCaption = &XClass::szContent;


A pointer to member cannot point to a static member of a class. Since szCaption is static the declaration:

char * XClass::* pwCaption = &XClass::szCaption;

is incorrect.

**
access specifier p.565
**

pb->f(); // ok B::f() is public, D::f() is invoked
pd->f(); // error: D::f() is private


I think:

Given the following code:

class B
{
public:
virtual int f();
};

class D
{
private:
virtual int f();
};

D dObj;
B* pb = &dObj;
D* pd = &dObj;

Which of the following is incorrect:
main()
{
b->f();
d->f();
}

Answer:
In:
pb->f();
Since f() is virtual and pB is pointing to a D object, D::f() is invoked. Eventhough f() is private in D, it is accessable since it is public in B.

In:
pd->f(); // error: D::f() is private
f() is private in D and it is not accessable.
**
Given:

Class A
{
virtual foo() = 0;
};

What is wrong with each of the following:

1)

Class B
{
A a;
};

2)

void f1(A pa);

3)
A f2();

4)

c = (A) b;

Abstract classes cannot be used for
- Variable or member data
- Argument types
- Function return types
- Types of explicit conversions


However, you can use pointers and references to abstract class types.




**

Published: 1996, Isaac Levy
@ Copyright, Isaac Levy, Los Angeles, CA