Throwing / throwing exceptions from C'tor static object in C ++

I have a case where I have to read the input file in C'tor, but sometimes this file does not exist. This object is usually held statically, so its C'tor is called when the dll loads. I cannot catch the exception that I throw if the file does not exist, because it is too early, and my executable crashes. I know that it is bad practice to throw exceptions from C'tor, but I cannot continue if the file does not exist, so I have to do this. Is there a way to catch the exception when loading the dll, and if not, is there a better solution for this scenario?

Thanks Gal

+3
source share
7 answers

I assume that the static object has the scope of the file (it is outside the function / class definition). You can move it to an access function and access it only through this function, for example:

class Object;
Object& getObject()
{
    static Object object;
    return object;
}

A static instance of the object will be initialized the first time the getObject () method is called. If the constructor of an object throws, you can easily catch an exception. You just need to remember that every call to getObject () is included in the try / catch block (or suffers from an exception that creates a stack chain); this may be a little inconvenient, but on the other hand, you can only solve the “first” call logically if you know which one is in the program logic stream.

+8
source

. RAII , , , , , .

, , - ( ). .

+3

, - , .

, . , auto_ptr.

+1

? Init(), , , .

+1

, , .

DLL: DLL , . ( , ). , dllmain.

.

Btw - DLL , , / . , .

+1

++ 11, unique_ptr<>:

// In some_file.hpp
#pragma once
#include <memory>
#include <stdexcept>

class CtorThrows {
public:
  CtorThrows (int value) {
    if (value < 10) {
      throw std::runtime_error("oops!");
    }
  }
};

class ClassWithStatic {
public:
private:
  static std::unique_ptr<CtorThrows> bad_member_; // <-- static member
};

// In some_file.cpp
#include "some_file.hpp"

// Create a lambda function to initialize the static member variable.
std::unique_ptr<CtorThrows> ClassWithStatic::bad_member_ = []() {
  try {
    int value = 5;  // in this case, it is a bad value

    // This only returns successfully if bad_value DOESN'T cause
    // the ctor to throw and exception.
    return std::make_unique<CtorThrows>(value);
  } catch (std::runtime_error &e) {
    std::cerr << "OOPs!  Here a nice error message" << std::endl;
    exit(1);
  }
  return std::unique_ptr<CtorThrows>(nullptr);
}();

unique_ptr , .

+1

One way could be to “design” this so that the invocation code (i.e. the code outside the DLL) is responsible for making sure that all the dll dependencies are in place. A function in the calling code that ensures that the dll dependencies, in this case the file, are in place and loaded before loading the library. If not, he can gracefully exit.

0
source

Source: https://habr.com/ru/post/1703347/


All Articles