How to delete an object if the constructor throws an exception?

So, we have a constructor that can throw an exception depending on the arguments passed to it, but we don’t know how to delete an object if this happens. The important part of the code:

try
{
    GameBase *gameptr = GameBase::getGame(argc, argv);
    if (gameptr == 0)
    {
        std::cout << "Correct usage: " << argv[PROGRAM_NAME] << " " << "TicTacToe" << std::endl;
        return NO_GAME;
    }
    else
    {
        gameptr->play();
    }
    delete gameptr;
}
catch (error e)
{
    if (e == INVALID_DIMENSION)
    {
        std::cout << "Win condition is larger than the length of the board." << std::endl;
        return e;
    }
}
catch (...)
{
    std::cout << "An exception was caught (probably bad_alloc from new operator)" << std::endl;
    return GENERIC_ERROR;
}

In the third line, it GameBase::getGame()calls the constructor for one of the games obtained from GameBase, and returns a pointer to this game, and these constructors can throw exceptions. The question is, how can we remove the object (partial?) That it points gameptrto if this happens? If an exception is thrown, we will exit the scope gameptrbecause we will leave the try block and cannot call delete gameptr.

+4
3

, GameBase::getGame.

, , . (.. ).

, ? new GameBase(...), - .


, -; "" . ;

#include <iostream>
using namespace std;
struct M {
    M() { cout << "M ctor" << endl; }
    ~M() { cout << "M dtor" << endl; }
};
struct C {
    M m_;
    C() { cout << "C ctor" << endl; throw exception(); }
    ~C() { cout << "C dtor" << endl; }
};
auto main() -> int {
    try {
        C c;
    }
    catch (exception& e) {
        cout << e.what() << endl;
    }
}

:

M ctor
C ctor
M dtor
std::exception

M m_ , unique_ptr shared_ptr ; :

#include <iostream>
#include <memory>
using namespace std;
struct M {
    M() { cout << "M ctor" << endl; }
    ~M() { cout << "M dtor" << endl; }
};
struct C {
    unique_ptr<M> m_;
    C() : m_(new M()) { cout << "C ctor" << endl; throw exception(); }
    ~C() { cout << "C dtor" << endl; }
};

.

+8

Foo* result = new Foo(), :

void* temp = operator new(sizeof(Foo)); // allocate raw memory
try {
  Foo* temp2 = new (temp) Foo(); // call constructor
  result = temp2;
} catch (...) {
  operator delete(temp); // constructor threw, deallocate memory
  throw;
}

, . , , , . , , ( ).

+3

, , , . !

int a = function(new A, new A);

, A, A. , A !

:

try{
auto first = std::make_unique<A>();
auto second = std::make_unique<A>();
int a = function(*first, *second);
...
-1
source

All Articles