[解決済み] プライベートコンストラクタはいつプライベートコンストラクタでなくなるのか?
2023-01-27 16:28:07
質問
ある型があり、その型のデフォルトコンストラクタをprivateにしたいとします。次のように書きます。
class C {
C() = default;
};
int main() {
C c; // error: C::C() is private within this context (g++)
// error: calling a private constructor of class 'C' (clang++)
// error C2248: 'C::C' cannot access private member declared in class 'C' (MSVC)
auto c2 = C(); // error: as above
}
素晴らしい
しかし、その後、コンストラクタは私が思っていたほどプライベートでないことが判明しました。
class C {
C() = default;
};
int main() {
C c{}; // OK on all compilers
auto c2 = C{}; // OK on all compilers
}
これは非常に驚くべき、予期しない、そして明らかに望ましくない動作であると私には思えます。なぜこれがOKなのでしょうか?
どのように解決するのですか?
C++14 8.4.2/5 [dcl.fct.def.default] にトリックがあります。
... ある関数は ユーザが提供する であり、最初の宣言で明示的にデフォルト化または削除されていない場合は 削除されていない場合は ...
ということは
C
のデフォルトコンストラクタは実際には
ではなく
ユーザーによって提供されたものではありません。そのため
C
はユーザ提供のコンストラクタを持たないため、8.5.1 [dcl.init.aggr]に従い集約されます。
このような場合 アグリゲート は,ユーザが提供するコンストラクタ(12.1),プライベート又はプロテクトされた非静的データメンバ(11)をもたない配列又はクラス(9項)である。 protected non-static data members (第11項)、基底クラス (第10項)、及び仮想関数 (第10.3項) をもたない配列又はクラスです。
関連
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー
-
[解決済み] C++で、あるコンストラクタを別のコンストラクタから呼び出す(コンストラクタ・チェイニングを行う)ことは可能ですか?
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] 仮想デストラクタはいつ使うのか?
-
[解決済み] 私的相続、公的相続、保護相続の違いについて
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない