2016-06-23 5 views
8

を持ってエラー:基底クラスのA1」は、Windowsプラットフォーム上でクラン3.7を使用してプライベートコピーコンストラクタ

次のコードを参照してください。

MyFile(31): 8: error: base class 'A1' has private copy constructor 
     B1(): A1(""){} 
      ^
MyFile(25): 2: note: declared private here 
     A1(const A1&) {} 
     ^

A1を作る:私は次のエラーを取得する

class A1 
{ 
public: 
    A1(char* name){} 
    virtual ~A1() {} 
private: 
    A1(const A1&) {} 
}; 

class B1 : public A1 
{ 
public: 
    B1(): A1(""){} 
}; 

をコピーコンストラクタpublic、エラーを排除します!

ここで何が起こりましたか?

注:

+5

@Andrewなぜコピーコンストラクタが必要なのでしょうか? – juanchopanza

+4

コードに '31'という行はありません。 –

+0

'A1'は文字列リテラルを受け入れるコンストラクタがないので、' A1( "") 'はエラーです。あなたが投稿したエラーはおそらくそのエラーからのカスケードです(元のエラーを修正すると消えてしまうので無視してください) –

答えて

3

文字列リテラルがchar*に変換できないため(このような廃止された変換がC++ 11より前に存在したため)、コンストラクタA1(char* name)を文字列リテラルを使用して呼び出すことはできません。むしろ、コンストラクタを呼び出すプログラムが不正であり、実装がコンパイルを拒否することが許されています。

このように、オーバーロードの解決は、他の選択肢を探します。引数の数が同じである唯一の代替可能性は、コピーコンストラクタです。

何らかの理由で、clangは文字列リテラルから暗黙的に変換することを好むと思われます。A1になり、リテラルの直接構造を使用してコピー初期化に使用できる一時的なものが作成されます。この動作は、混乱しているコンパイルエラーにつながります。

どちらの代替も正しく構成されておらず、clangは適切にそれについて警告します:warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]。標準モードをC++ 11よりも古いものに設定すると、プログラムはコンパイルされます(この場合、プログラムは非推奨の変換を使用していても整形式になります)。私たちは、変換を許可しない場合は興味深いことに、その後、プログラムはさらに、現在の標準モードでコンパイルされます。

class A1 
{ 
public: 
    explicit A1(char* name){} // note the explicit 
    virtual ~A1() {} 
private: 
    A1(const A1&) {} 
}; 

G ++は異なった動作をし、あなたのプログラムは、(当然の適切な警告で)罰金コンパイル。どちらのコンパイラもこの点で標準に準拠しているようです。

ストーリーのモラル:常に警告も読んでください。この場合、警告は完全に明確で簡単に解決できましたが、同じバグがバグの解決に役立たない間接的なエラーを引き起こしました。

+0

ありがとう!コピーctorをpublicに設定して(理解のためだけに)、デバッガを実行すると、まずA1(char * name)ctorを実行してからctorをコピーすることがわかります。明示的なA1(char * name)を使用すると、このctorだけが呼び出されます。 –

6

を期待通りに(私が必要として)

A1(const char* name) 

を変更することによって、私はエラーとまったくを取得していないことは、私は、これは、診断がどのように生成されるかの単なる人工物であることを想像してコンパイルします。まず、検索があなたが

  • のみ他の候補を知っているように、あなたの
  • (それはコールが、何でもありません)「と呼んで」ctorのはchar*を服用すると、一致しないと一致するようにコンストラクタを見つけようと

    • private
    • コンパイラは、それがそうすることでその作業
    • を作るためにあなたの""引数から一時的A1をインスタンス化できるかどうかを確認しようとしている、再びそれを見つけることができるすべてはprivateコンストラクタです
    • コンパイラはそのことについて文句を言うことを決定した何かを行う前

    一つが、これは実装の問題の品質であることを主張するかもしれません。

    面白いことに、GCC 6.1.0 (even in pedantic C++14 mode) compiles your code as originally writtenは、壊れたリテラル変換の警告のみを吐き出します。

  • 関連する問題