C++ quiz
If assumptions in the code below are true what value would be the final value printed by this program? int main(int argc, char** argv) { // assume result printed is 4 std::cout << sizeof(int) << std::endl; int *x = new int; // assume result printed is 0x60000000 std::cout << x << std::endl; std::cout << x + 3 << std::endl; return 0; }
undefined In pointer addition and subtraction if both operands and the result do not point inside the same array (or 1 past the last element of the array) the result is undefined.
What value should be printed for x? #include <iostream> int main() { int x = int() = 3; std::cout << x << std::endl; return 0; }
won't compile int() creates a temporary variable which is an rvalue. The temporary variable that is created can not be assigned to since it is an rvalue. Thus this code should not compile
What will get printed? #include <iostream> using namespace std; void function(int * p){ int * pointer = new int(5); p = pointer;} int main(){ int * pointer = new int(1); function(pointer); cout<<*pointer<<endl; return 0;}
1 Function takes pointer by value, so despite it points to the orginal value pointer itself is copied and ogrinal value will not be modified.
Which of the following operators does NOT indicate a sequence point in the code? && || ? = ,
= All of them except the assignment operator indicate a sequence point. "At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place. (§1.9/7)" e.g. in 'x=y++' has '++' site effect after '='. C++11 does not define 'sequence point'
Which of the following implementations of the reset function is best for initializing the array to all zero. class foo{ public: foo(){ reset(); } private: void reset(){ // A // memset(x, 0, 50); // B // memset(x, 0, sizeof(x)); // C // memset(x, 0, 50 * 4); // D // memset(x, 0, 50 * sizeof(x)); } long x[50]; };
B It is the only answer that is portable. C will work on platforms where long is 4 bytes, but many platforms have 8 byte long.
Which lines below (if any) are ill-formed? #include <iostream> struct A { A(int& var) : r(var) {} int &r; }; int main(int argc, char** argv) { int x = 23; A a1(x); A a2 = a1; a2 = a1; return 0; }
a2 = a1; It is ill-formed to use an implicitly defined assignment operator when one of the members that will need to be copied is a reference. (Line 18)
What value gets printed by the program? #include <iostream> int foo(int x, int y = x) { return x+y+1; } int main(int argc, char** argv) { std::cout << foo(2) << std::endl; return 0; }
code is ill-formed The program is ill-formed. Parameters of a function can not be used in default argument expressions.
Inside namespace 'foo'. Does the function 'bar' can access the variable 'x' which is declared in the same namespace? #include <iostream> namespace foo { void bar() { x++; } int x; } int main(int argc, char** argv) { return 0; }
false Names used in a namespace must be declared before before their use
The code below would declare an array of references, if we had properly initalized the references. True or false? int main() { int& x[50]; return 0; }
false There is no such thing as an array of references. Also there are no references to references or pointers to references. && - might be rvalue reference
The variable x is accesible in the else clause of this program? int main(int argc, char** argv) { if ( argc > 2 ) { int x = 5; } else { } return 0; }
false Variables declared in blocks of if,else-if,else are local to the block they were declared in.
What value gets printed by the program? #include <iostream> int main() { int x = 3; switch(x) { case 0: int x = 1; std::cout << x << std::endl; break; case 3: std::cout << x << std::endl; break; default: x = 2; std::cout << x << std::endl; } return 0; }
nothing, it is ill-formed Jumping into a block and bypassing a declaration with an initialization is ill-formed. In this example there are cases which would bypass the declaration and initialization of block scope x declaration. It does not apply to 'if becouse 'Switch' is like 'goto' 'if' isn't. Standard section 6.7 "It is possible to transfer into a block, but not in a way that bypasses declarations with initialization."
What value gets printed by the program? #include <iostream> struct Foo { Foo(int d) : x(d) {} int x; }; int main() { double x = 3.14; Foo f( int(x) ); std::cout << f.x << std::endl; return 0; }
nothing, its ill-formed Any construct that could possibly be considered a declaration is a declaration. In this example, the second line of main is interpreted as a function declaration in preference to an object declaration with initialization.
In addition to c-style, which casts can be used to cast an int to a pointer or a pointer to an int?
reinterpret_cast Only reinterpret_cast (or c-style casts) can be used to cast an int to a pointer or a pointer to an int
In addition to c-style, which casts can be used to cast an int into an enum?
static_cast Only static_cast (or c-style casts) can be used to cast an int to an enum
Of the variable definitions below, which ones have external linkage and can be accessed from another translation unit? int w = 1; static int x = 2; const int y = 3; extern const int z = 4; int main(int argc, char** argv) { return 0; }
w,z w has external linkage. x has internal linkage. y has internal linkage. z has external linkage
What is the maximum number of implicitly defined constructors that this struct will have? struct A { A(A& a) { } A(double d) {} int val; };
0 There will be no implicity defined constructors for this struct. * Not sure if true in c++11
What value is printed out for the variable x? #include <iostream> int x; int main() { int y; std::cout << x << std::endl; std::cout << y << std::endl; return 0; }
0 variables with static storage duration are zero initialized. Note that x has static storage duration even though the static keyword is not used. According to the standard: "All objects which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration"
What gets printed? #include <iostream> int main() { for (int i = 0; i < 4; ++i) { switch (i) { case 0 : std::cout << "0"; case 1 : std::cout << "1"; continue; case 2 : std::cout << "2"; break; default : std::cout << "D"; break; } std::cout << "."; } return 0; }
0112.D. Based on sections 6.4.2 p6 and 6.6.1 p1 of the standard, The first case label to match the given switch condition is executed,furthermore all subsequent cases (including the default case) will be executed until a break, continue, return or end of switch is encountered. In this case the continue not only exits from the switch but goes directly to the next iteration of the loop.
What value gets printed by the program? #include <iostream> int main(int argc, char** argv) { int x = 0; int y = 0; if (x++ && y++){ y += 2; } std::cout << x + y << std::endl; return 0; }
1 If the first operand to the logical AND operator evaluates to false the second operand is guaranteed not to evaluate. Note: the logical OR operator is guaranteed not to evaluate the second operand if the first operand is true. Note: for the logical AND and OR operators, all side effects of the first expression, except for destruction of temporaries, happen before the second expression is evaluated.
Which of the following statements are true? 1) Conversion functions of class A convert from class A into another type 2) Conversion functions of class A are used to convert from another given type into class A 3) Converting constructors must be callable with a single argument
1, 3 The 2nd statement is not true
What value gets printed by the program? #include <iostream> int main(int argc, char** argv) { int x; x = 1, 2, 3; for (int i =0 ; i<1, i<6 ; i++) std::cout << x return 0; }
111111 The operands to the comma operator are evaluated from left to right. The value of the left hand expression is discarded. The type and value of the result are the type type and value of the right hand operand. Note: assignment takes precedence over the comma operator, so in this case x=1 is evaluated first; than x, 2, 3
What value for y gets printed in the program below? #include <iostream> const int x = 12; int main(int argc, char** argv) { enum dog { x = x, y }; std::cout << y << std::endl; return 0; }
13 An Enumeration's point of declaration is after its definition (which includes the initialization). Therefore in this case the value of the enum 'x' is initialized with the global 'x' which equals 12.
What is the output of the program? #include <iostream> struct A { virtual int foo(int x = 5) { return x * 2; } }; struct B : public A { int foo(int x = 10) { return x * 3; } }; int main(int argc, char** argv) { A* a = new B; std::cout << a->foo() << std::endl; return 0; }
15 The method B::foo is called but with the default argument of 5 from A::foo. "A virtual function call uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides."
What gets printed? #include <iostream> struct Car { Car() : price(20000) {} Car(double b) : price(b*1.1) {} double price; }; struct Toyota : public virtual Car { Toyota(double b) : Car(b) {} }; struct Prius : public Toyota { Prius(double b) : Toyota(b) {} }; int main(int argc, char** argv) { Prius p(30000); std::cout << p.price << std::endl; return 0; }
20000 All sub-objects representing virtual base classes are initialized by the constructor of the most derived class. If the constructor of the most derived class does not specify a mem-initializer for a virtual base class V, then V's default construtor is called to initialize the virtual base class subobject. *Remove 'virtual' and you get 3300 This mechanisism ensures that derivered classes initialization order does not influent base class initialization.
What value gets printed by the program? #include <iostream> struct Foo { int x; operator int() { return 21; } }; int main(int argc, char** argv) { Foo f; f.x = 11; std::cout << (0?3:f) << std::endl; return 0; }
21 The 2nd and 3rd operands to the conditional operator must be of the same type. If one of the two can be converted to the other, the conversion will occur. Note: if a conversion exists for each of the operands into the other's type, the program is ill-formed.
What value does foo print out? #include <iostream> const int SIZE = 5; struct tester { void foo() { std::cout << SIZE << std::endl; } enum { SIZE = 3 }; }; int main(int argc, char** argv) { tester t; t.foo(); return 0; }
3 Names defined at any point in a class are in scope in all member functions of the class. Thus the enum SIZE is in scope in the function foo and hides the global variable SIZE.
If you have an array of characters allocated with new. Which of the following is the best way to modify the size of the array? 1. Use the realloc function from libc 2. Delete the existing array, then allocate a new array and copy the data from the old array to the new array 3. Allocate a new array, copy the data from old array to the new array and then delete the old array 4. It is not possible to do such an operation in C++
3 You can not use realloc, because realloc may call free on memory allocated with new which is bad. You can do the same thing realloc does manually, but make sure not to delete the original array until after copying the data. Also you may want to check the size of the new array. If the new array is smaller than the old one, you may not need to do the reallocation depeding on the business logic.
How many times is Hello World printed by this program? #include <iostream> struct BS { BS(){ std::cout << "Hello World" << std::endl; } unsigned int color; }; struct mid1 : virtual public BS { }; struct mid2 : virtual public BS { }; struct mid3 : public BS { }; struct mid4 : public BS { }; struct DR : public mid1, public mid2, public mid3, public mid4 { }; int main(int argc, char** argv) { DR d; return 0; }
3 times One time for the first virtual occurences of BS in the heirarchy and once for each non-virtual occurence of BS. mid1 and mid2 together have one. mid3 and mid4 each have one.
According to the C++ standard which of the following declarations for the "main" function are valid? 1 int main(int argc, char** argv) 2 int main(char** argv, int argc) 3 int main() 4 inline int main(int argc, char* argv[]) 5 int main(char* argv[], int argc) 6 void main() 7 int main(int argc, char* argv[]) 8 static int main() 9 int main(int argc, char* argv[], char* options[])
3, 7, 9 According to section 3.6.1 pg2, main must return an int, and must have either no parameters or (int argc ,char* argv[]) as its first set of parameters. And in section 3.6.1 pg3: A program that declares main to be inline or static is ill-formed.
What gets printed? #include <iostream> int foo(int i) { return 2 } double foo(double d) { return 4.0; } struct Computer { int foo(int i) { return 8; } }; struct Gateway : public Computer { double foo(double d) { return 16.0; } }; int main(int argc, char** argv) { Gateway g; std::cout << foo(1) + foo(1.0) + g.foo(1) + g.foo(1.0) ; return 0; }
38 When calling global foo, the function is overloaded and each foo is called once depending on the type of the argument. When calling the member foo, Gateway::foo hides Computer::foo so Gateway::foo is called twice.
What value gets printed by the program? #include <iostream> int foo(int y); int foo(int x) { return x+1; } int main(int argc, char** argv) { int x = 3; int y = 6; std::cout << foo(x) << std::endl; return 0; }
4 The trick here is, we change the parameter names from the function declaration to function definition. This is legal, and only the parameter names in the function definition are used.
What should get printed in the program below? #include <iostream> using namespace std; class foo{ public: foo() : z(x+1), y(2), x(3) { cout << "z: " << z << endl; } private: int x; int y; int z; }; int main(int argc, char** argv){ foo f; return 0; }
4 the value of z is initialized to 4. According the C++ standard: non-static data members shall be initialized in the order they were declared in the class definition, regardless of the order of the mem-initializers. Therefore x is initialized to 3 before z is initialized to X + 1.
How many times is Hello World printed by this program? #include <iostream> struct BS { BS(){ std::cout << "Hello World" << std::endl; } }; struct mid1 : public BS { }; struct mid2 : public BS { }; struct mid3 : public BS { }; struct mid4 : public BS { }; struct DR : public virtual mid1, public virtual mid2, public virtual mid3, public mid4 { }; int main(int argc, char** argv) { DR d; return 0; }
4 times Virtual inheritance affects the class that is inherited virtually. Therefore the BS base class is not inherited virtually and there are 4 of them within 1 DR object. The virtual inheritance statements in this code are affecting the classes mid1, mid2, mid3, mid4 and not BS.
What is the value of y at the end of main? const int x = 5; int main(int argc, char** argv) { int x[x]; int y = sizeof(x) / sizeof(int); return 0; }
5 The local x does not hide the global x until the end of the declaration. A local name will hide a global after the end of the declaration but before the beginning of initialization.
What gets printed for the value of z? #include <iostream> struct Foo { Foo(int n) : x(n++), y(n++), z(n++) {} int x; int y; int z; }; int main(int argc, char** argv) { Foo f(3); std::cout << "x: " << f.x << std::endl; std::cout << "y: " << f.y << std::endl; std::cout << "z: " << f.z << std::endl; return 0; }
5 There is a sequence point after the initalization of each base and member, thus the code is well-formed and defined
What is the output of the program? #include <iostream> class Foo { public: char c; static double sd; double d; int i; }; int main(int argc, char** argv) { Foo f = { 72, 3.14 }; std::cout << f.c + f.d + f.i << std::endl; return 0; }
75.14 "An aggregate is an array or a class with no user-declared constructors, no private or protected non-static data members, no base classes, and no virtual functions." Aggregates can be initialized by "brace-enclosed, comma separated list of initializer-clauses for the members of the aggregate, written in increasing subscript or member order." Static data members are skipped during this type of initialization so 3.14 initializes d and not sd in this example "If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be value-initialized". So in this example i is value-initialized to 0.
Which lines will cause a complilation error? struct A{ A(int) { } // converting constructor A(int, int) { } // converting constructor (C++11) operator bool() const { return true; } }; struct B{ explicit B(int) { } explicit B(int, int) { } explicit operator bool() const { return true; } }; int main(){ A a1 = 1; A a2(2); A a3 {4, 5}; A a4 = {4, 5}; A a5 = (A)1; if (a1) ; bool na1 = a1; bool na2 = static_cast<bool>(a1); B b1 = 1; B b2(2); B b3 {4, 5}; B b4 = {4, 5}; B b5 = (B)1; if (b2) ; bool nb1 = b2; bool nb2 = static_cast<bool>(b2); }
A a1 = 1; OK: copy-initialization selects A::A(int) A a2(2); OK: direct-initialization selects A::A(int) A a3 {4, 5}; OK: direct-list-initialization selects A::A(int, int) A a4 = {4, 5}; OK: copy-list-initialization selects A::A(int, int) A a5 = (A)1; OK: explicit cast performs static_cast if (a1) ; OK: A::operator bool() bool na1 = a1; OK: copy-initialization selects A::operator bool() bool na2 = static_cast<bool>(a1); OK: static_cast performs direct-initialization B b1 = 1; ERROR: copy-initialization does not consider B::B(int) B b2(2); OK: direct-initialization selects B::B(int) B b3 {4, 5}; OK: direct-list-initialization selects B::B(int, int) B b4 = {4, 5}; ERROR: copy-list-initialization does not consider B::B(int,int) B b5 = (B)1; OK: explicit cast performs static_cast if (b2) ; OK: B::operator bool() bool nb1 = b2; ERROR: copy-initialization does not consider B::operator bool() bool nb2 = static_cast<bool>(b2); OK: static_cast performs direct-initialization
Which lines below should not compile? #include <iostream> struct A { A(int x) : n(x) {} int n; }; int main(int argc, char** argv) { A a1; A a2(2); A a3(a2); return 0; }
A a1; If any user-declared constructor is present in the class, then no default constructor will be created implicitly. Additionally if no user declared copy constructor is declared, then an implicit copy constructor will be created by the compiler. In this example there is a user-declared constructor which prevents the default constructor from existing, but a copy constructor is still created implicitly.
What gets printed by this program? #include <iostream> struct Shape{ virtual Shape* duplicate(){ std::cout << "SHAPE" << std::endl; return new Shape; } virtual ~Shape() {} }; struct Box : public Shape{ virtual Box* duplicate(){ std::cout << "BOX" << std::endl; return new Box; } }; int main(int argc, char** argv) { Shape* s1 = new Box; Shape* s2 = s1->duplicate(); delete s1; delete s2; return 0; }
BOX BOX is printed. The return type of an overriding virtual function must have either the same type as the function it is overriding or both functions must return a pointer or reference with the same cv-qualifications whereby the class pointed or reffered to in the overridden function is an unambiguous and accessible direct or indirect base class of the class pointed or referred to in the overriding function.
Which lines of code below should not compile? struct Foo{}; struct Bar{}; int main() { Foo* f = new Foo; Bar* b1 = f; Bar* b2 = static_cast<Bar*>(f); Bar* b3 = dynamic_cast<Bar*>(f); Bar* b4 = reinterpret_cast<Bar*>(f); Bar* b5 = const_cast<Bar*>(f); return 0; }
Bar* b1 = f; Bar* b2 = static_cast<Bar*>(f); Bar* b3 = dynamic_cast<Bar*>(f); Bar* b5 = const_cast<Bar*>(f); Only reinterpret_cast can be used to convert a pointer to an object to a pointer to an unrelated object type. The dynamic cast would fail at run-time, however on most compilers it will also fail to compile because there are no virtual functions in the class of the pointer being casted.
What will be the output of the following program? #include <iostream> struct Foo { Foo() {} virtual void go() const { std::cout << "Foo" << std::endl; } }; struct Bar : public Foo { Bar() {} void go() { std::cout << "Bar" << std::endl; } }; int main(int argc, char** argv) { Foo* f = new Bar; f->go(); Bar f2; f2.go(); return 0; }
Foo Bar Class Bar has two instances of the 'go' methods; const virtual method nad non-const method. Non-const method is profered for non-const objests. Class Foo has only one 'go' method.
What will get printed: #include <iostream> struct Shape { virtual Shape* duplicate(){ return new Shape;} virtual void print(const int x =1){std::cout << "SHAPE" << std::endl;} virtual ~Shape() {} }; struct Box : public Shape { virtual Box* duplicate(int x, int y){return new Box;} virtual void print(int x, int k){std::cout << "BOX" << std::endl;} }; struct Geo : public Box { virtual Geo* duplicate(){return new Geo;} virtual void print(int x = 3){std::cout << "GEO" << std::endl;} }; int main(int argc, char** argv) { Shape* s1 = new Geo; Shape* b1 = s1->duplicate(); b1->print(); delete s1; delete b1; return 0; }
GEO Virtual functions reborn after the overriding - like a phoenix from ashes.
What gets printed by this program? #include <iostream> struct Shape{ virtual void print(){ std::cout << "SHAPE" << std::endl; } virtual ~Shape() {} }; struct Box : public Shape { virtual void print(int i){ std::cout << "BOX" << std::endl;} }; int main(int argc, char** argv) { Shape* s = new Box; s->print(); delete s; return 0; }
SHAPE SHAPE is printed. A function with a different signature does not override a function in a base class even if the function name is the same.
What gets printed by this program? #include <iostream> struct Shape { void print() { std::cout << "SHAPE" << std::endl; } }; struct Box : public Shape { void print() { std::cout << "BOX" << std::endl; } }; int main(int argc, char** argv) { Shape* s1 = new Box; s1->print(); return 0; }
SHAPE Shape::print is not a virtual function. Therefore Shape::print is called even though s1 points to a Box object. If print was virtual, then BOX would be printed.
Given the code below what will be the output to stdout? #include <cstdio> void foo(int v1, int v2, int v3, int v4) { printf("%d %d %d %d\n",v1,v2,v3,v4); } int main() { int lut[] = { 1, 2, 3, 4 }; int idx = 0; foo(lut[idx++],lut[idx++],lut[idx++],lut[idx++]); return 0; }
Undefined behavior As per the standard section 5.4: "Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified58) Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined."
From line xXx in the code below which labels can you access using a goto statement? void foo(int x) { pointa: //xXx pointb: pointc: printf("end of function\n"); } int main(int argc, char** argv) { foo(5); pointd: return 0; }
a, b, c Labels have function scope. This means they can be accessed from anywhere within the function where they are defined but not in any other function of the program. Labels are the only construct in C++ with function scope.
Which, if any, of the member function definitions below are ill-formed? #include <iostream> int g_x = 44; struct Foo { int m_x; static int s_x; Foo(int x) : m_x(x) {} int a(int x = g_x) { return x + 1; } int b(int x = m_x) { return x + 1; } int c(int x = s_x) { return x + 1; } }; int Foo::s_x = 22; int main(int argc, char** argv) { Foo f(6); std::cout << f.a()<< f.b() << f.c() << std::endl; return 0; }
b b is ill-formed. Non-static members can not be used as default arguments. Default arguments have to constructed at compile-time (However at the execution-time its value might be altered).
Which of the following lines should NOT compile? int main() { int a = 2; int* b = &a; int const* c = b; b = c; return 0; }
b = c; int* can be implicity converted to int const* -- 4.4. There is no implicit conversion from int const* to int*.
Which of the following lines should NOT compile? int main() { int a[54] = {}; int b[54] = {}; int* x = a; int* const y = a; b = x; b = y; return 0; }
b = x; b = y; Arrays can be implicity converted to pointers without casting -- 4.2. There is no implicit conversion from pointers to arrays.
Which lines below should not compile? #include <iostream> class Bar{ protected: static int x; int y; }; int Bar::x = 33; class Barrel : public Bar{ public: void foo(Bar **b, Barrel **d) { b->y = 0; d->y = 0; Bar::x = 0; Barrel::x = 0; } }; int main(int argc, char** argv) { Barrel b; b.foo(&b, &b); return 0; }
b->y = 0; Access to non-static protected members of a base class can not be via a pointer or reference to the base class.
What value gets printed by the program? #include <iostream> int main() { int sum = 0; int array[3][] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}; for (int i = 0; i < 3 ; ++i) { for (int j = 2; j < 3 ; j++) { sum += array[i][j]; } } std::cout << sum << std::endl; return 0; }
code is ill-formed Only the first constant expression in a multiple dimension array can be ommitted. Therefore the declaration of the array in this example is ill-formed.
What is the output of the program? #include <iostream> int main(int argc, char** argv) { // assume address of x is 0x822222222 int x = 3; int*& rpx = &x; std::cout << rpx << std::endl; return 0; }
code is ill-formed References can not be initialized with values, so this program is ill-formed. In this case rpx should be initialized with a pointer to an int, not with the address of an int.
What is the output of the program? #include <iostream> struct Foo { Foo() {} void go() { std::cout << "Foo" << std::endl; } }; struct Bar : public Foo { Bar() {} void go() { std::cout << "Bar" << std::endl; } }; int main(int argc, char** argv) { Bar b; const Foo f = b; f.go(); return 0; }
code is ill-formed The code is ill-formed. Non-const member functions can not be called on const objects.
What is the output of the program? #include <iostream> struct BS{ unsigned int color; }; struct car : public BS {}; struct truck : public BS {}; struct city : public car, public truck {}; int main(int argc, char** argv) { city c; c.color = 3; std::cout << c.color << std::endl; return 0; }
code is ill-formed The code is ill-formed. The non-static members of a base class, that is an indirect or direct base class more than once, can not be referred to without qualification.
What gets printed by this program? #include <iostream> struct Shape { virtual void print(){ std::cout << "SHAPE" << std::endl; } virtual ~Shape() {} }; struct Box : public virtual Shape{ void print(){ std::cout << "BOX" << std::endl; } }; struct Sphere : public virtual Shape{ void print(){ std::cout << "SPHERE" << std::endl; } }; struct GeoDisc : public Box, public Sphere {}; int main(int argc, char** argv) { Shape* s = new GeoDisc; s->print(); delete s; return 0; }
code is ill-formed The code is ill-formed. Virtual functions must have a unique "final overrider" that overrides all other instances of that function in its inheritance heirarchy. In this case neither Box::print nor Sphere::print override each other, so the condition is not met and the GeoDisc class is ill-formed
What value gets printed by the program? #include <iostream> int foo(int x, int y) { return x+y; } double foo(double x, double y) { return x+y; } int main(int argc, char** argv) { double (*ptr)(int, int); ptr = foo; std::cout << ptr(3,8) << std::endl; return 0; }
code is ill-formed The return type of a function does not alter the signature (for function overloading). However, the return type of a function DOES change the "type" of the function and thus the assignment of foo to ptr in not valid.
Which lines of code below should cause the program to be undefined? struct Foo { virtual ~Foo() {} }; struct Bar : public Foo {}; int main(int argc, char** argv) { Foo* f = new Bar; delete f; f = 0; delete f; Foo* fa = new Bar[10]; delete [] fa; fa = 0; delete fa; return 0; }
delete [] fa; deleting NULL pointers have no effect. deleting a pointer to a base class which points to a derived object is legal assuming the base destructor is virtual. deleting an array of objects using a base class pointer is undefined.
Given the code below, the variable 'y' can be accessed in which blocks of code? int main(int argc, char** argv) { if ( argc > 10 ) { } else if (int y = argc - 1 ) { } else { //int y; } return 0; }
else-if, else The variable declared in the else-if did not exist before its declaration and can not be used after the end of the else clause. Variables declared in conditions of if,else-if,else structures can be used in all subsequent conditions and bodies of the if,else-if,else structure. *Commented line cause redeclaration error, Variables declared in else-if and within else-if block has the same range.
A function call is always an rvalue. True or false?
false A function call can be an lvalue if and only if the return value is a reference
The code below is legal? int x = 5; template <typename T> class x { T member; }; int main(int argc, char** argv) { class x<int> y; return 0; }
false A template class name can not be the same as any other name in the same declarative region. This is also the case for typedef names.
The code below declares and defines variable x? extern int x;
false An extern declaration does not define the variable unless it is also initialized in the same statement
True or False, the program below will print NOT EQUAL #include <iostream> struct Foo {}; struct Bar {}; int main(int argc, char** argv) { Foo* f = new Foo; Bar* b = new Bar; if ( f == b ) std::cout << "EQUAL" << std::endl; else std::cout << "NOT EQUAL" << std::endl; return 0; }
false Distinct pointer types can not be compared with equality operators
Static member functions of classes can be virtual. True or false?
false Static member functions can not be virtual
Which of the following functions are found when called in main during name lookup? #include <iostream> namespace standards { struct datastructure {}; void foo(const datastructure& ds){} void bar(){} } int main(int argc, char** argv) { standards::datastructure ds; foo(ds); bar(); return 0; }
foo This is called koenig lookup or argument dependent name lookup. In this case, the namespace 'standards' is searched for a function 'foo' because its argument 'ds' is defined in that namespace. For function 'bar', no additional namespaces are searched and the name is not found. More details are in 3.4.2.
What gets printed by the code below? #include <iostream> class A { public: void foo() const { std::cout << "A"; } }; class B { public: void foo() const { std::cout << "B"; } }; class C : public A, public B { using A::foo; public: using B::foo; }; int main() { C c; c.foo(); return 0; }
ill-formated Error caused by c.foo(); The accessibility property of the introduced foo method from the A type is private in the C type, hence it will not be publicly accessible. This is the case regardless of the fact that the A type is publicly derived and the foo method has public accessibility in A type. This is further explained in the C++ standard, section 7.3.3 pg 15 by the following: "The alias created by the using- declaration has the usual accessibility for a member-declaration." The alias 'using B::foo' doesn't change anything as only more restrictive accessibility is taken under acount.
What gets printed by this program? #include <iostream> struct Shape { virtual void print() { std::cout << "SHAPE" << std::endl; } virtual ~Shape() {} }; struct Box : private Shape { virtual void print() { std::cout << "BOX" << std::endl; } }; int main(int argc, char** argv) { Shape* s = new Box; s->print(); delete s; return 0; }
ill-formed An implicit conversion from a pointer to a derived class, to a pointer to an inaccessible (private inheritance) base class is ill-formed. Thus the assignment of the new Box to Shape* is ill-formed. *protected inheritance does NOT work either.
What gets printed? #include <iostream> struct A { A() : val() {} A(int v) : val(v) {} A(A a) : val(a.val) {} int val; }; int main(int argc, char** argv) { A a1(5); A a2(a1); std::cout << a1.val + a2.val << std::endl; return 0; }
ill-formed It is illegal to have a constructor whose first and only non-default argument is a value parameter for the class type.
What gets printed by this program? #include <iostream> struct Shape { virtual Shape* duplicate(){ return new Shape;} virtual void print(){std::cout << "SHAPE" << std::endl;} virtual ~Shape() {} }; struct Box : public Shape { virtual Box* duplicate(){return new Box;} virtual void print(){std::cout << "BOX" << std::endl;} }; int main(int argc, char** argv) { Shape* s1 = new Box; Box* b1 = s1->duplicate(); b1->print(); delete s1; delete b1; return 0; }
ill-formed The program is ill-formed. The return type of the virtual function that is called dynamically is converted to the return type of the overridden function. In this case the result of the duplicate() function is a pointer to a Box object but converted to a Shape pointer. Therefore the assignment from the return value to b1 is ill-formed.
What gets printed? #include <iostream> struct A { A() : val(0) {} A(int v) : val(v) {} A(A& a) : val(a.val) {} int val; }; int main(int argc, char** argv) { const A a1; const A a2(5); const A a3 = a2; std::cout << a1.val + a2.val + a3.val << std::endl; return 0; }
ill-formed The third line of main tries to initialize a3 with a2, but A's copy constructor takes a non-const reference which violates a2's const declaration.
What value gets printed by the program? #include <iostream> int foo(int x, int y) { return x+y; } int foo(const int x, const int y) { return x+y+1; } int main(int argc, char** argv) { const int x = 3; const int y = 2; std::cout << foo(x,y) << std::endl; return 0; }
ill-formed There can only be one function with the same signature. Altering the cv qualification of parameters does not change the function signature. Therefore the two foo functions have the same signature and the program is ill-formed.
What gets printed? #include <iostream> struct mybase { int x; template <int RANGE> virtual void print() { std::cout << RANGE + x + 1 << std::endl; } }; struct myderived : public mybase { template <int RANGE> void print(){std::cout << RANGE + x + 2 << std::endl;} }; int main(int argc, char** argv) { mybase* b = new myderived; b->x = 1; b->print<5>(); return 0; }
ill-formed A member function template can not be virtual. Destructors and copy constructors cannot be templates as well.
What is the value of x at the end of main? int main(int argc, char** argv) { int x = 50 % -7; return 0; }
implementation defined if either operand to a modulus operator is negative the result is implementation defined
In addition to const_cast, which cast can be used to cast away constness?
none Only const_cast (or c-style casts) can be used to cast away constness
True or false? Every expression is an lvalue or an rvalue?
true Its true, see Standard 3.10/1
The code below is legal. True or false? #include <iostream> const char* Foo() { return "Hello World"; } int main() { const char* str = Foo(); std::cout << str << std::endl; return 0; }
true String literals have static storage duration, therefore they can be referenced anywhere in the translation unit, even though it is defined in a function
Non-const static member variables must be defined outside of the class for them to be used? struct test { static int x; }; int test::x;
true The declaration of a static data member in a class does not define it.
The code below is legal? int x = 5; class x { }; int main(int argc, char** argv) { class x y; return 0; }
true You can have a class and a regular variable with the same name. However the class name will been hidden and the elaborated-type-specfier must be used to access the class name.
What is the value of the local variable x at the end of main? int x = 5; int main(int argc, char** argv) { int x = x; return 0; }
undefined The local x in main hides the global x before the local x's initializer is considered. Therefore the local x is being initialized with itself (the local unitialized variable)
Given the assumptions in the comments, what values is printed for x? int main(int argc, char** argv) { // assume result printed is 4 std::cout << sizeof(int) << std::endl; int x = 0x1000; x = x << 32; std::cout << std::hex << x << std::endl; return 0; }
undefined The result of a shift operation is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand
What value does size print out? #include <iostream> const int SIZE = 5; struct tester { int array[SIZE]; enum { SIZE = 3 }; void size() { std::cout << sizeof(array) / sizeof(int); } }; int main(int argc, char** argv) { tester t; t.size(); return 0; }
undefined, il-formated 3.3.6/3 says if reordering member declarations in a class yields an alternate valid program the program is ill-formed. In this case the enum SIZE is not in scope when array is declared making the array size 5. However if the members were reordered to declare array after the definition of the enum the array size would be 3. Thus since reordering member declaration changes the program, it is undefined.
Which of the following variables can be accessed in foo's function try block handler? void foo(int x) try { int y = 2; throw 1; } catch(int e) { } int main(int argc, char** argv) { foo(3); return 0; }
x, e Function parameters are accessible in the try handler. Function local variables are NOT accessible in the try handler.
Will "Hello World" be printed by the program below? int main(int argc, char** argv) { int array[33]; if ( &array[4] < &array[23] ) { std::cout << "Hello World" << std::endl; } return 0; }
yes Pointer comparison with greater and less than relational operators is defined within the same array.
Will "Hello World" be printed by the program below? struct Foo { int x; int y; }; int main(int argc, char** argv) { Foo f; if ( &f.x < &f.y ) { std::cout << "Hello World" << std::endl; } return 0; }
yes Relational operators can be used to do pointer comparison of non-static members in the same object where the definitions of the members is not seperated by an access specifier. The member declared first will evaluate to lower. Note: other than this case, the only other time relational operators can be used to compare pointers is when the addresses point to elements in the same array. For all other cases, the result of relational operators on pointers is unspecified.