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

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

ただいまの
回答率

90.48%

  • C++

    3608questions

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

  • C++11

    108questions

    C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

C++11で、デストラクタ = deleteとする意味について

受付中

回答 3

投稿

  • 評価
  • クリップ 4
  • VIEW 4,813

maisumakun

ユーザーランキング総合1位

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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+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.
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/21 18:11

    インスタンス化阻止なら、コンストラクタを=deleteしたほうが確実ですし(むろんnewも不能)…積極的にデストラクタでやる理由もないですよね…

    キャンセル

  • 2016/05/21 18:27

    コンストラクタは3つ(デフォルト、コピー、ムーブ)潰さないといけないので、1つで済むデストラクタはちょっとだけ楽かも。
    しかし、意図が分かりにくいし、newはできてしまうし、「積極的にデストラクタでやる理由もない」に賛成です。

    キャンセル

0

ローカル変数にできなくなるって面白いですね。

majiponiさんの回答をみて思いついたのはシングルトンオブジェクトの破棄は静的メソッドで行うので、デストラクタはないというようにわかりやすくするとかはあるかもしれないと思いました

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

関連した質問

  • 解決済

    [C++] Pimplイディオム [コードデザイン]

    こんばんは,みなさんはAPIやその他配布物を作成されるとき,Pimplイディオムを使用されていますか? また使用時は,Implに隠ぺいする情報には何を選択していますか? 例) 1

  • 解決済

    クラスのメンバポインタ(?)について

    クラスについて質問です class Product{ char *name; int price; } としたときnameと*nameとどどちらがメンバなのでしょうか。

  • 解決済

    c++ 動的確保がうまくいかない

    先ほども別に質問をし回答をいただいたのですが、その後の直しがうまくいきません。 汎用クラスを使い動的にメモリを確保したいのですが、解放の仕方が出来ません。 ★で囲まれた部分をそのま

  • 解決済

    c++ delete演算子の使い方

    前提・実現したいこと 下記のコードのようにnew演算子でobjを利用して、delete演算子でobjを消そうとしましたがエラーが発生しています。この場合、どのようにしてobjを消

  • 解決済

    深い継承を行ったときの仮想デストラクタの振る舞い

    以下のコードで、CBaseのデストラクタを、仮想デストラクタにすることで、アップキャストした場合でも、派生クラス(CSub, CSub1)のデストラクタが呼ばれます。 しかし、C

  • 解決済

    Graphics::TBitmap の破棄時の処理について

    C++builder6というレガシーな開発環境を利用してWindowsアプリケーションの作成を行っています。 私が行っている作業は既存のソースコードに対し機能追加を行うというもの

  • 解決済

    new の使いかた

    現在、ゲームプログラミングの勉強をしているものです。 c++以外はあまり勉強できていない為c++での回答をお願いします。 メモリの動的確保の利便性、というか使い道のようなものに

  • 解決済

    [C++] 配列の使い分け?について

    こんにちは。 あらかじめ配列の要素数が分かっているわけではなく、コンストラクタの引数によって要素数が決定し、それ以降要素数は変化しないような場合は、std:vectorを固定

同じタグがついた質問を見る

  • C++

    3608questions

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

  • C++11

    108questions

    C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。