C++ (Part1)

Posted on at


The classes you design can do more (in terms of allowed operations) than what you could figure out from just looking at their member function declarations. The C++ Standard defines a number of cases where certain expressions involving your type are valid, even though there are no corresponding member function declarations. Sometimes this is just what you need; but sometimes the additional operations you never asked for can have grave negative impact on your program correctness.

For the first case, let’s consider implicitly declared special member functions. I often ask this question in job interviews. In the below code, what is the bug and how to fix it?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

class String

{

  char * _str;

 

public:

  String(const char * str)

    : _str( new char[strlen(str) + 1] )

  {

    strcpy(_str, str);

  }

   

  ~String()

  {

    delete [] _str;

  }

 

  bool equal(const String& rhs) const

  {

    return strcmp(_str, rhs._str) == 0;

  }

};

 

String make_string()

{

  return String("cat");

}

In case, you didn’t see the problem immediately, here is the answer. You may have wanted it or not, but the compiler has implicitly declared (and perhaps defined later) the copy constructor for String. The compiler does not know that you are managing a resource and generates a shallow copy. After the copy, the two instances think they are managing the very same resource: just wait for the problem to happen.

I am far from saying that auto-generating copy operations is something unwanted. In fact, having to always provide your custom definition in every class would be a nightmare. It is only about this case.

There is more than one way of fixing the above example; but the question we should be really answering is what precautions to take in order never to see this bug in the code in the first place. We leave this question open for now, though.

For the second case, let’s consider another bug. We have a class FixedDecimal that represents decimal numbers with fixed-point arithmetic. Class FixedDecimal supports multiplication: by other FixedDecimal and by an int:

1

2

3

4

5

FixedDecimal<2> d ("1.20");

FixedDecimal<2> f ("0.50");

 

assert ((d * 2).to_string() == "2.40");

assert ((d * f).to_string() == "0.60");



About the author

toshi-warraich

Good Boy with very bad thoughts.

Subscribe 0
160