0

このコードのコンパイル方法がわかりません。誰かがそこで何が起こっているのか説明してもらえますか.

#include <iostream>

using namespace std;

class B
{
public:    
    B(const char* str = "\0") //default constructor
    {
        cout << "Constructor called" << endl;
    }    

    B(const B &b)  //copy constructor
    {
        cout << "Copy constructor called" << endl;
    } 
};

int main()
{ 
    B ob = "copy me";    //why no compilation error.
    return 0;
}

optput は次のとおりです。呼び出されるコンストラクター

PS: これ以上にふさわしいタイトルが思い浮かびませんでした。より良いタイトルを考えられる方は、修正してください。

4

7 に答える 7

10

の型は で"copy me"ありchar const[8]、 に減衰しchar const *ます。デフォルトのコンストラクターは ではないためexplicit"copy me"暗黙的に に変換できるためBobその暗黙的に変換された一時オブジェクトからコピー構築できますB

デフォルトのコンストラクターが宣言されexplicitていた場合、次のいずれかを記述する必要がありました。

B ob1 = B("copy me");
B ob2("copy me");

コピー コンストラクター宣言されexplicitていた場合、次のいずれかを指定する必要がありました。

B ob3(B("copy me"));
B ob4("copy me");

実際には、すべてのコピーは中途半端なコンパイラによって省略され、最終的には常に 1 つのデフォルト コンストラクター呼び出しになります。

于 2012-09-16T12:18:23.593 に答える
7

これだから

B ob = "copy me";

コピーコンストラクターを呼び出します。これは引数を取り、クラスにはコンストラクターがconst B &b ありますB

B(const char* str = "\0")

として定義されていませんexplicit

コンパイラは、1 つの暗黙的な変換を行うことができます。


それで、ここで何が起こるか:

B ob = "copy me";

は:

  1. B提供された を使用して、一時的な名前のないオブジェクトを作成しますconst char* str- これは許可class Bされていexplicitます。つまり、型を持つすべてのオブジェクトはBconst char*
  2. で作成obした一時オブジェクトを使用して、オブジェクトを作成し1.ます。
于 2012-09-16T12:18:42.823 に答える
7

デフォルトのコンストラクターにキーワードexplicitを追加して、暗黙的な変換を防ぐ場合。その後、コンパイルされません。あなたの答えは暗黙の変換です。

于 2012-09-16T12:19:22.627 に答える
4

これは、代入ステートメントが暗黙的に次のように変換されるためです。

B ob("copy me");

これを試してコンパイルを失敗させます (explicitキーワードを見てください):

#include <iostream>

using namespace std;

class B
{
public:    
    explicit B(const char* str = "\0") //default constructor
    {
        cout << "Constructor called" << endl;
    }    

    B(const B &b)  //copy constructor
    {
        cout << "Copy constructor called" << endl;
    } 
};

int main()
{ 
    B ob = "copy me";    //why no compilation error.
    return 0;
}
于 2012-09-16T12:19:13.353 に答える
3

[コンパイルすべきではない] 指定された行のデータ型が一致しません

との間の変換を可能にする引数としてB取るのコンストラクターが存在するため、コンパイル エラーは発生しません。const char*const char*B

于 2012-09-16T12:18:38.020 に答える
0

これは暗黙の変換によるものです。Default コンストラクターに Explicit を追加して試してください。コンパイルに失敗します。

于 2012-09-16T12:32:24.970 に答える
-1

編集: Kerrek SB との話し合いの後、C++11 標準のコピーを入手しました。私は間違っていました、一時的なものがあります。新たに得た理解を反映するために、この返信を編集しています。

15 年前、私は C++ を非常によく知っていました (最初の標準がリリースされた頃でした)。1998 年後半から使用していないため、多くのことを忘れており、最近の標準についてはほとんど何も知りません。

コードは正しいです。

 B ob = "copy me";    //why no compilation error.

エラーはありません。これは、初期化された変数の宣言として解析されます。Bタイプ、ob変数の名前"copy me"、初期化子です。

初期化子は型であり、クラス B には、型付きの単一の引数const char*を取るコンストラクターがあります。const char*そのコンストラクターはによって制限されていると宣言されていないexplicitため、このコンテキストで使用できます。

一時オブジェクトが作成されてからコピーされるか (両方の行が表示されます)、またはコピーが省略され、変換コンストラクターのみが呼び出されて宛先で直接構築されます (1 行のみが表示されます)。コピー コンストラクターに副作用がある場合でも、標準では明示的にこれを許可しています。

プログラムの実行により、 Constructor called to stdout が出力されます。という名前の Copy コンストラクターも出力する場合と出力しない場合があります。エラーはありません。

于 2012-09-16T12:40:18.083 に答える