C++11で、デストラクタ = deleteとする意味について
受付中
回答 3
投稿
- 評価
- クリップ 5
- VIEW 13K+
C++では、仮想関数の宣言に= 0
とすることで純粋仮想関数を指定する「純粋指定子」がありましたが、C++11では、
- デフォルトコンストラクタ・コピーコンストラクタ・代入演算子・デストラクタについて、コンパイラの自動生成したものを使うと明示する
= default
- 特定のメンバ関数がないことを宣言する
= delete
のような指定子が加わっています。
そして、この「= delete
」で宣言したメンバ関数を呼ぶようなコードを書けば、(呼び出しが明示的か暗黙のうちにかを問わず)コンパイルエラーとなります。代入やインスタンス化など、特定の操作を禁止できるという意味では便利です。
そして、構文上は~someClass() = delete;
とできるのですが、以下のような挙動になりました(手元のg++ 4.7.2で-std=gnu++11
として動かしてみました)。
- 宣言自体は問題なく可能
- そのクラスのローカル変数を宣言しようすると、スコープアウト時の破棄でデストラクタが呼ばれるためコンパイルエラー
- ポインタを宣言して
new
することは可能(他のメンバ関数も呼べる)
* ただし、delete
を書くとコンパイルエラー
このような、「new
はできるけどdelete
が不可能な上に自動変数にもできない」クラスができあがったのですが、果たして何かに実用できるものなのでしょうか。それとも、じつは「デストラクタを= delete
するのは未定義」なのでしょうか。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+2
デストラクタを呼べない。そのことには理由があります。
「デストラクタを呼ぶべきではない。」これが理由です。
もっとはっきりと書くなら、「自動解放のタイミングでは適切な処理ができない」「引数をつけて呼び出せないデストラクタを利用しての解放を禁止すべきである。」という状況が考えられます。
プログラマに常に明示的解放を要求することは、必要になる場合があります。そのようなときにデストラクタの削除は効果的です。
オブジェクトの初期化・廃棄は、キャストとmalloc、freeと配置new/deleteで可能です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
こんにちは。
MinGW(gcc) 5.2.0では下記だけでもerror: use of deleted function 'Foo::~Foo()'
でした。
struct Foo
{
~Foo() = delete;
};
Foo foo;
スタックオーバーフローに幾つかQAがありましたが、スタックに獲得できないようにする効果がある旨しか読み取れませんでした。どんな時便利か、回答している人はいないようなに見えます。(もっと英語力が欲しい。orz)
使える場面としては、インスタンスを作らないクラスしか思いつきません。「このクラスはインスタンスを作るな」とお手軽に明示するために指定するイメージです。正直、使う場面はないような。
n3337の147ページ7.1.6.2 Simple type specifiersの5
でデストラクタをdeleteしている、何かのサンプル・コードが記載されているのですが、やはり意味がある使い方には見えませんでした。
template<class T> struct A { ~A() = delete; };
template<class T> auto h()
-> A<T>;
template<class T> auto i(T) // identity
-> T;
template<class T> auto f(T) // #1
-> decltype(i(h<T>())); // forces completion of A<T> and implicitly uses
// A<T>::˜A() for the temporary introduced by the
// use of h(). (A temporary is not introduced
// as a result of the use of i().)
template<class T> auto f(T) // #2
-> void;
auto g() -> void {
f(42); // OK: calls #2. (#1 is not a viable candidate: type
// deduction fails (14.8.2) because A<int>::~A()
// is implicitly used in its decltype-specifier)
}
template<class T> auto q(T)
-> decltype((h<T>())); // does not force completion of A<T>; A<T>::˜A() is
// not implicitly used within the context of this decltype-specifier
void r() {
q(42); // Error: deduction against q succeeds, so overload resolution
// selects the specialization “q(T) -> decltype((h<T>())) [with T=int]”.
// The return type is A<int>, so a temporary is introduced and its
// destructor is used, so the program is ill-formed.
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
ローカル変数にできなくなるって面白いですね。
majiponiさんの回答をみて思いついたのはシングルトンオブジェクトの破棄は静的メソッドで行うので、デストラクタはないというようにわかりやすくするとかはあるかもしれないと思いました
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.33%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる