Classes Flashcards

Chapter 7

1
Q

When does a const member assume its constness in an object’s lifecycle

A

Unlike other member functions, constructors may not be declared as const. When we create a const object of a class type, the object does not assume its “constness” until after the constructor completes the object’s initialization. Thus, constructors can write to const objects during their construction.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

How can we ask compiler to provide a default constructor

A

struct Data
{
Data() = default;
};

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

How to change a const data member

A
By including mutable keyword
class Screen {
public:
void some_member() const;
private:
mutable size_t access_ctr; // may change even in a const object
// other members as before
};
void Screen::some_member() const
{
\++access_ctr; // keep a count of the calls to any member function
// whatever other work this member needs to do
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Is friend-ship transtive

A

It is important to understand that friendship is not transitive. That is, if class Window_mgr has its own friends, those friends have no special access to Screen.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Does defining a friend function inside a class work?

A
No
Even if we define the function inside the class, we must still provide a declaration outside of the class itself to make that function visible. A declaration must exist even if we only call the friend from members of the friendship granting class:
struct X {
friend void f() { /* friend function can be defined in the class
body */ }
X() { f(); } // error: no declaration for f
void g();
void h();
};
void X::g() { return f(); } // error: f hasn't been declared
void f(); // declares the function defined inside X
void X::h() { return f(); } // ok: declaration for f is now in scope
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Are class members and functions and member process ( or parsed ) by compiler in the same phase

A
Class definitions are processed in two phases:
• First, the member declarations are compiled.
• Function bodies are compiled only after the entire class has been seen.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Can a class redefine an outer scope typedef into an inner scope one

A

In a class, if a member uses a name from an outer scope and that name is a type, then the class may not subsequently redefine that name:

typedef double Money;
class Account {
public:
Money balance() { return bal; } // uses Money from the outer scope
private:
typedef double Money; // error: cannot redefine Money
Money bal;
// …
};
It is worth noting that even though the definition of Money inside Account uses the same type as the definition in the outer scope, this code is still in error.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

In which order are members initialized in a class

A

Members are initialized in the order in which they appear in the class definition: The first member is initialized first, then the next, and so on. The order in which initializers appear in the constructor initializer list does not change the order of initialization.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

What are delegating constructors

A

The new standard extends the use of constructor initializers to let us define so-called delegating constructors. A delegating constructor uses another constructor from its own class to perform its initialization. It is said to “delegate” some (or all) of its work to this other constructor.

class Sales_data {
public:
// nondelegating constructor initializes members from corresponding arguments
Sales_data(std::string s, unsigned cnt, double price):
bookNo(s), units_sold(cnt), revenue(cnt*price) {
}
// remaining constructors all delegate to another constructor
Sales_data(): Sales_data("", 0, 0) {}
Sales_data(std::string s): Sales_data(s, 0,0) {}
Sales_data(std::istream &is): Sales_data()
{ read(is, *this); }
// other members as before
};
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Default initialization VS Value initialization

A
The default constructor is used automatically whenever an object is default or value initialized. Default initialization happens
• When we define nonstatic variables (§ 2.2.1, p. 43) or arrays at block scope without initializers
• When a class that itself has members of class type uses the synthesized default constructor
• When members of class type are not explicitly initialized in a constructor initializer list

Value initialization happens
• During array initialization when we provide fewer initializers than the size of the array
• When we define a local static object without an initializer
• When we explicitly request value initialization by writing an expressions of the form T() where T is the name of a type (The vector constructor that takes a
single argument to specify the vector’s size uses an argument of this kind to value initialize its element initializer.)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How to initialize an object with default constructor

A

Without using ()

Sales_data obj(); // oops! declares a function, not an object
Sales_data obj2; // ok: obj2 is an object, not a function

Refer Most vexing parse

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How many level conversion will compiler apply when for class conversion

A

Only One Class-Type Conversion Is Allowed
In we noted that the compiler will automatically apply only one class-type conversion. For example, the following code is in error because it implicitly uses two conversions:

// ERROR: requires two user-defined conversions:
// (1) convert "9-999-99999-9" to string
// (2) convert that (temporary) string to Sales_data
item.combine("9-999-99999-9");

If we wanted to make this call, we can do so by explicitly converting the character string to either a string or a Sales_data object:
// ok: explicit conversion to string, implicit conversion to Sales_data
item.combine(string(“9-999-99999-9”));
// ok: implicit conversion to string, explicit conversion to Sales_data
item.combine(Sales_data(“9-999-99999-9”));

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Whats the use of explicit keyword infront of ctor declaration

A

We can prevent the use of a constructor in a context that requires an implicit conversion by declaring the constructor as explicit:

class Sales_data {
public:
Sales_data() = default;
Sales_data(const std::string &s, unsigned n, double p):
bookNo(s), units_sold(n), revenue(p*n) { }
explicit Sales_data(const std::string &s): bookNo(s) { }
explicit Sales_data(std::istream&);
// remaining members as before
};
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What is an aggregate class

A
An aggregate class gives users direct access to its members and has special initialization syntax. A class is an aggregate if
• All of its data members are public
• It does not define any constructors
• It has no in-class initializers
• It has no base classes or virtual functions

struct Data {
int ival;
string s;
};

Data val1 = { 0, “Anna” };
The initializers must appear in declaration order of the data members.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What is a litral class

A

An aggregate class whose data members are all of literal type is a literal class.

A nonaggregate class, that meets the following restrictions, is also a literal class:
• The data members all must have literal type.
• The class must have at least one constexpr constructor.
• If a data member has an in-class initializer, the initializer for a member of builtin type must be a constant expression, or if the member has class type, the initializer must use the member’s own constexpr constructor.
• The class must use default definition for its destructor, which is the member that destroys objects of the class type.

A constexpr constructor must initialize every data member. The initializers must either use a constexpr constructor or be a constant expression.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Can we use an incomplete type as a static member

A
Yes, static data member can have incomplete type. In
particular, a static data member can have the same type as the class type of which it is a member.
class Bar {
public:
// ...
private:
static Bar mem1; // ok: static member can have incomplete type
Bar *mem2; // ok: pointer member can have incomplete type
Bar mem3; // error: data members must have complete type
};
17
Q

Can static member be used as a default argument for a member function

A
Yes, 
class Screen {
public:
// bkground refers to the static member
// declared later in the class definition
Screen& clear(char = bkground);
private:
static const char bkground;
};