Hi,
I am writing an application in which I make
a map of strategies keyed by a string symbol. In
order to construct the strategies I pass the constructor
a filename, out of which it reads out some data, into an initializing map.

It is possible that some data might be missing from the initializing map,
in which case I simply want to skip this strategy. I am
thinking that, to implement this I need to throw an exception
if the data is missing. But I am unsure how to implement this, as
I have never used exceptions before. Inside the constructor, my proposed
code looks like:
if( calMap_.find(string("MuSCurve"))==calMap_.end()) {
delete _estimatorIntegrator;
throw MissingData();
}

The calling code looks like:

while (!symbolStream.eof()) {
symbolStream >> symbol;
std::string calPathBase(calFileDirectory_ + symbol);
try{ TradingStrategy* ts( new TradingStrategy(calPathBase,symbol)); }
catch ( MissingData() ) { continue;}
_strategies[symbol] = ts;
}

Do I have to delete any new-ed pointers in the constructor before
throwing? Do I need to delete the ts pointer in the calling code,
if the exception is thrown?

Recommended Answers

All 3 Replies

Don't put throw in constructors because that will require the calling program to put all the code that uses the class in one huge try/catch block. A better design is to have a constructor that doesn't need throw and then write another method that uses it.

Hi,
I am writing an application in which I make
a map of strategies keyed by a string symbol. In
order to construct the strategies I pass the constructor
a filename, out of which it reads out some data, into an initializing map.

It is possible that some data might be missing from the initializing map,
in which case I simply want to skip this strategy. I am
thinking that, to implement this I need to throw an exception
if the data is missing. But I am unsure how to implement this, as
I have never used exceptions before.

Throwing an exception is one option, but is this truly an error condition? You're just catching the exception and swallowing it, which suggests alternative strategies. For example, a factory can be used to verify the file and pass the verified data into a private constructor. That way you can simply return a null pointer if the file is bogus rather than throw an exception:

class TradingStrategy {
    ...
public:
    static TradingStrategy *create(const string& file);
private:
    TradingStrategy(map<string, string> initMap);
};

TradingStrategy *TradingStrategy::create(const string& file)
{
    map<string, string> tempMap;
    
    // Initialize tempMap from the file
    
    if (tempMap.find("MuSCurve") == tempMap.end())
        return 0;
        
    return new TradingStrategy(tempMap);
}
while (symbolStream >> symbol) {
    TradingStrategy *ts = TradingStrategy::create(calFileDirectory_ + symbol);

    if (ts != 0)
        _strategies[symbol] = ts;
}

The issue here is that your TradingStrategy class is actually doing two things:

  • Parsing a file
  • Managing a strategy

It's generally recommended that each class have only a single responsibility, and adding more introduces problems like you're having ("How do I handle file parsing errors?"). The factory solution keeps the two tasks related, but not so tightly coupled that you can't logically separate responsibilities. The factory handles parsing and verifying of the file, then defers strategy creation and management to the object.

The big question with exceptions is: is the situation expected or unexpected? If it's expected, then that falls under normal flow of execution and probably doesn't warrant throwing an exception. If it's unexpected, that's an error condition that needs to be properly handled. Ignoring error conditions is rarely the correct response. At the very least you want to log the error or try to recover from it.

@Narue

Thank you, this is obviously better than what I was doing.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.