Home > Blockchain >  Use of sstream causing a deleted copy constructor
Use of sstream causing a deleted copy constructor

Time:10-22

So I am a CS student working on a project for exception handling (Try/catch). My teacher told us to implement the sstream library so we could use it in a class that outputs a message that includes a passed parameter of type int. For some reason unknown to me, when I use it, or even when I declare a variable of type stringstream, it causes a compile error with error message:

"copy constructor of 'tornadoException' is implicitly deleted because field 'ss' has a deleted copy constructor"

Here is my code. I am at a loss.

main.cpp

#include <iostream>
#include <string>
#include <sstream>
#include "tornadoException.h"

using namespace std;


int main() 
{
  try{
    int tornado = 0;
    cout << "Enter distance of tornado: ";
    cin >> tornado;
    
    if(tornado > 2){
      throw tornadoException(tornado);
    }
    else{
      throw tornadoException();
    }
  }
  catch(tornadoException tornadoObj){
    cout << tornadoObj.what();
  }
}

tornadoException.cpp

#include <iostream>
#include <string>
#include <sstream>

#include "tornadoException.h"

using namespace std;

  tornadoException::tornadoException(){
    message = "Tornado: Take cover immediately!";
  }

  tornadoException::tornadoException(int m){
    ss << "Tornado: " << m << "miles away!; and approaching!";
    message = ss.str();
 
  }

  string tornadoException::what(){
    return message;
  }

tornadoException.h

#ifndef tornadoException_h
#define tornadoException_h

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

class tornadoException{
public:

  tornadoException();

  tornadoException(int m);

  string what();
private:
  stringstream ss;
  string message;
};

#endif

CodePudding user response:

stringstream has a deleted copy constructor, which means that a stringstream object cannot be copied.

Since your tornadoException class has a stringstream variable, this means that your class cannot be copied either.

In your main function, you capture the exception by value, which means that you are copying it into the tornadoObj variable - which is not allowed.

Try changing the line catch(tornadoException tornadoObj) to catch(tornadoException& tornadoObj) so that you're getting a reference to the exception instead of a copy of it.

This is actually a general rule: An exception shall always be caught by reference, not by copy: Core Guidelines E.15

CodePudding user response:

Alright, figured out the error but I'll leave up this post since I couldn't find the answer anywhere else. The problem was that I declared the stringstream buffer as a private variable in the class. The buffer needs to be declared locally within the function declaration it is being used in, in this case right before the loading of the buffer in the implementation file:

tornadoException::tornadoException(int m){
stringstream ss;
ss << "Tornado: " << m << " miles away!; and approaching!";
message = ss.str();
}
  • Related