0

Just failed an interview because of this, and I'm still confused:

class A
{
public:
    A(int a) : a_(a) {}
    
    // Copy constructor
    
    // Assignment operator
    
private:
    int a_;
};
 
class B : public A
{
public:
    B(int a, int b) : A(a), b_(b) {
    }
    
    // Copy constructor
    
    // Assignment operator
    
private:
    int b_;
};

How do you implement the copy constr/assignment op, and why does the constructor of B have to have an A initialized in the initializer list? It doesn't work if it's not in the list.

Larry Jing
  • 383
  • 1
  • 5
  • 26
  • 1
    It appears you could use a [good C++ book](https://stackoverflow.com/a/388282/4641116). – Eljay Jan 21 '21 at 20:59
  • Here's how to do copy constructor: https://stackoverflow.com/a/1021639/4641116 – Eljay Jan 21 '21 at 21:03
  • @M.A I fail to see the relevance, an initialiser list would be required even if everything in `A` was public. – john Jan 21 '21 at 21:20
  • @john you could have a setter inside the constructor body. – Mansoor Jan 21 '21 at 21:21
  • 1
    @M.A No you couldn't, base classes must be constructed before the body of the parent class constructor is entered, in other words you must use an initialiser list. – john Jan 21 '21 at 21:22
  • @john ah yes, the default constructor is not generated, thank you. – Mansoor Jan 21 '21 at 21:27

2 Answers2

2

why does the constructor of B have to have an A initialized in the initializer list?

A only has one constructor which takes an int. B has A as a base class, which means that every B object must first construct an A object. How else are you going to construct that A object with it's required parameter except by using an initialiser list?

john
  • 85,011
  • 4
  • 57
  • 81
2

How do you implement the copy constr/assignment op

Trick question, I think. In this case the best option is to do absolutely nothing. Neither class contains (and owns) any resources requiring more than the default special member functions. Observe the Rule of Zero.

Some style guides recommend explicitly defaulting special member functions. In this case

class A
{
public:
    A(int a) : a_(a) {}
    
    A(const A &) = default;
    A& operator=(const A &) = default;
    
private:
    int a_;
};

may be appropriate.

why does the constructor of B have to have an A initialized in the initializer list?

All class members and base classes must be fully constructed before entering the body of a constructor.

B(int a, int b) 
{ // Entering constructor's body. A must be constructed before we get here.
}

A has no default constructor, so the constructor it does have must be explicitly called in the initializer list to construct the base class before the construction of B can proceed.

Addressing comment

A's copy constructor and assignment operator are trivial:

A(const A & src): a_(src.a_)
{

}

A& operator=(const A & src)
{
    a_ = src.a_;
    return *this;
}

B is a bit trickier because it also has to make sure A is copied

B(const B & src): A(src), // copy the base class
                  b_(src.b_)
{

}

B& operator=(const B & src)
{
    A::operator=(src); // assign the base class by explicitly calling its 
                       // assignment operator
    b_ = src.b_;
    return *this;
}

Note: If I were hiring, I'd take the programmer who called me out on the trick question over the programmer who did the extra work and risked an unforced error.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Thank you for the explanation. But say you had to write out the copy constr/assignemnt op just for the sake of practice. Would it be the same as default for both of them? How would it work for B? – Larry Jing Jan 25 '21 at 21:01
  • 1
    @LarryJing Updated answer. – user4581301 Jan 25 '21 at 21:40
  • [Here is a link to a more complicated case where the Copy and Swap Idiom is employed.](https://stackoverflow.com/questions/25973103/copy-swap-in-base-and-derived-class) – user4581301 Jan 25 '21 at 21:43