Is it better to let the function throw or throw in the constructor?

I think it’s easier to explain with an example. Let’s take a class that models the speed of a Formula 1 car, the interface may look something like this:

class SpeedF1
{
public:
  explicit SpeedF1(double speed);
  double getSpeed() const;
  void setSpeed(double newSpeed);
  //other stuff as unit 
private:
  double speed_;
};

Now a negative speed does not make sense in this particular case and no value is greater than 500 km / h. In this case, the constructor and the setSpeed ​​function may throw exceptions if the supplied value is not within the logical range.

I can introduce an additional layer of abstraction and insert an additional object instead of a double one. The new object will be a wrapper around the double, and it will be created and will never be changed. The class interface will be changed to:

class ReasonableSpeed
{
public:
  explicit ReasonableSpeed(double speed); //may throw a logic error
  double getSpeed() const;
  //no setter are provide
private:
  double speed_;
};

class SpeedF1
{
public:
  explicit SpeedF1(const ReasonableSpeed& speed);
  ReasonableSpeed getSpeed() const;
  void setSpeed(const ReasonableSpeed& newSpeed);
  //other stuff as unit 
private:
  ReasonableSpeed speed_;
};

SpeedF1 , , reset .

, (, ), . , , , .

, :

?

+5
5

-, . , a double . , , , raw double.

-, . Setters - , , - -. () , .

: . , .

, . ++ Im .

. . , . .

+6

. . , "" , , . , , , .

, , ReasonableSpeed ( , , ). .

+1

ReasonableSpeed, .

ReasonableSpeed, .

+1

, , .. . Unix Rule of Rarsimony:

: , , .

'Big here makes sense of both a large amount of code and internal complexity. Providing programs with great service opportunities. Because people are reluctant to throw away the visible product of a large number of jobs, large programs offer excessive investment in approaches that are unsuccessful or suboptimal.

you may like to choose the first simpler approach. If you do not want to reuse the class ReasonableSpeed.

0
source

I would recommend doing this instead:

class SpeedF1
{
public:
  explicit SpeedF1(double maxSpeed);
  double getSpeed() const;
  void accelerate();
  void decelerate();
protected:
  void setSpeed(double speed);
  //other stuff as unit 
private:
  double maxSpeed_;
  double curSpeed_;
};

SpeedF1::SpeedF1(double maxSpeed) maxSpeed_(maxSpeed), curSpeed_(0.0) { }

double SpeedF1::getSpeed() const { return curSpeed_; }

void SpeedF1::setSpeed(double speed) {
    if(speed < 0.0) speed = 0.0;
    if(speed > maxSpeed_) speed = maxSpeed_;
    curSpeed = speed;
}

void SpeedF1::accelerate() {
    setSpeed(curSpeed_ + SOME_CONSTANT_VELOCITY);
}


void SpeedF1::decelerate() {
    setSpeed(curSpeed_ - SOME_CONSTANT_VELOCITY);
}
0
source

All Articles