質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1255閲覧

#define SAFE_DELETE(x) if(x != nullptr){ delete x; x = nullptr;} という行為は正解なのかどうか?

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/05/03 03:43

編集2021/05/03 04:15

提示コードの#define 部ですが二重deleteは良くないので#defineを使って防いでいるのですがこれは正解なのでしょうか?関数で書くと型の問題で汎用性が損なるのでこうしました。 提示コードの下のEntryクラスですが使い方としてif()文を使ってもしnullptrじゃないとき等を使って分岐するとコードが見ずらくなるので使ってみましたが正しいのでしょうか?

cpp

1#include <iostream> 2#include <cassert> 3 4 5//#define NDEBUG 6 7#define SAFE_DELETE(x) if(x != nullptr){ delete x; x = nullptr;} 8int main() 9{ 10 int* a = new int(); 11 12 SAFE_DELETE(a); 13 SAFE_DELETE(a); 14 15 return 0; 16}

cpp

1#include "Entry.hpp" 2#include "Title.hpp" 3#include "Game.hpp" 4#include "GameOver.hpp" 5 6 7 8 9Entry::Entry() 10{ 11 changeScene = Scene::Title; 12 13 title = nullptr; //タイトル 14 game = nullptr; //ゲーム 15 gameOver = nullptr; //ゲームオーバー 16} 17 18void Entry::Loop() 19{ 20 21 //シーン推移 22 if (title != nullptr) 23 { 24 title->Loop(this); 25 } 26 else if (game != nullptr) 27 { 28 game->Loop(this); 29 } 30 else if (gameOver != nullptr) 31 { 32 gameOver->Loop(this); 33 } 34 35 36 37 //シーン削除 38 switch (changeScene) 39 { 40 case Scene::Title: 41 { 42 SAFE_DELETE(game); 43 SAFE_DELETE(gameOver); 44 title = new Title(); 45 }; 46 break; 47 48 case Scene::Game: 49 { 50 SAFE_DELETE(title); 51 game = new Game(); 52 }; 53 break; 54 55 case Scene::GameOver: 56 { 57 SAFE_DELETE(game); 58 gameOver = new GameOver(); 59 }; 60 break; 61 } 62} 63 64 //シーン切り替え 65void Entry::MoveTo(Scene e) 66{ 67 changeScene = e; 68} 69 70 71 72

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/05/03 04:05

現在質問文を編集中です。
guest

回答2

0

ベストアンサー

二重deleteは良くないので#defineを使って防いでいるのですがこれは正解なのでしょうか?

ご自身の意図した通りに動くのであれば、その意味で「不正解」ではないでしょう。

しかし、一般的にその書き方は「正解」とは言えないと思います。
理由は2つ。

1つ目。「関数で書くと型の問題で汎用性が損なるので」と理由を挙げられていますが、テンプレートを使えば次の例のように十分に関数で書け、マクロを避けることができます。なので、#define で敢えて書く意義がありません。

C++:テンプレート版

1template <typename T> 2static inline void SAFE_DELETE(T* &p) { 3 if ( p != nullptr ) { 4 delete p; 5 p = nullptr; 6 } 7}

2つ目。今のC++(C++11~)には std::uniq_ptr 等のスマートポインタと呼ばれるライブラリが標準であります。「安全性」を重視したいのなら、素のポインタで new,delete して自前で何か策を講じるのではなく、標準で用意されているそういった機能を使うべきです。

投稿2021/05/03 04:30

angel_p_57

総合スコア1672

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

nullptrじゃないとき等を使って分岐するとコードが見ずらくなるので使ってみましたが正しいのでしょうか?

ほとんど意味がありません。delete nullptr;何もしないことが保証されています(参考)。

投稿2021/05/03 04:22

maisumakun

総合スコア145208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/05/03 04:25

同様に、free(NULL)も安全に何もしないことが保証されています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問