2017-05-22 20 views
3

なぜ文字列パラメータへのconst参照は文字列リテラルを取ることができますか? "hello"のような文字列リテラルは変数ではないので、なぜこのコードは有効ですか?なぜ文字列パラメータへのconst参照は文字列リテラルを取ることができますか?

class CVector { 
    public: 
     int x, y; 
     CVector() {}; 
     ~CVector() { delete ptr; } 
     string* ptr; 
     void doSomething(const string& str) { ptr = new string(str); } 
     void print() { cout << "\n" << *ptr; } 
}; 
int main() 
{ 
    result.doSomething("asdas"); 
    result.print(); 
    return 0; 
} 

まず第一に、私はパラメータとして参照がコピー処理を避け、直接引数として取る変数にアクセスするために使用された(私はまだかかわらず、正しいかもしれない)と思いました。しかし、文字列リテラル "asdas"は変数ではないので、なぜパラメータが文字列リテラルを引数として取ることができますか?私はパラメータstrが参照であるので、そのエンティティのエイリアスになるでしょうか?もしそうなら、文字通りは変数になりましたか?

const参照の代わりにstring& strで構成されていないと、リテラルはstrの構成で使用されますか?

参照が存続している限り、const参照は参照されたエンティティを生かしていませんか?もしそうなら、なぜあなたはそれを文字通りにしますか?

+0

単純に言えば、文字列リテラルをとり、文字列インスタンスを作成する変換(つまりctor)があります。 – Kobi

答えて

6

あなたは

result.doSomething("asdas"); 

を行うと、コンパイラはあなたがdoSomething(const char[]);を持っているかどうかを確認するために見て、何も見つかりません。適切な機能がないので、const char[]から構築できるものをとり、doSomething(const string& str)を見つける過負荷を見つけようとします。コンパイラは1つのユーザ定義変換を行うことが許可されているので、文字列リテラルから一時的にstd::stringを構築し、一時参照をconstに渡して関数に渡します。リテラルはSTRの構築に使用されるように

は、パラメータリストは、文字列&のstrの代わりにconst参照で構成されていないでしょうか?

いいえ、これはconstへの参照でのみ機能し、通常の参照は一時的なものにバインドできないため、通常の参照では機能しません。

参照が存在している限り、const参照は参照されたエンティティを生かしていませんか?もしそうなら、なぜあなたはそれを文字通りにしますか?

constへの参照は、関数ローカルオブジェクトである場合にのみ、オブジェクトの有効期間を延長します。関数のスコープの内部では、その関数を呼び出した式は終了していないが、動作しないクラスのstd::stringへの参照を保持しようとすると、オブジェクトは生き残ります。

が効果的にあなたは、コードは次のように、

int main() 
{ 
    CVector result 
    { 
     std::string temp = "asdas"; 
     result.doSomething(temp); 
    } 
    result.print(); 
    return 0; 
} 
+0

関数に渡されるオブジェクトは、リテラル自体ではなく、作成された一時的な 'string'であることに注意してください。 –

+0

'result.result.doSomething(" asdas ");(" asdas ");'が正しく表示されない –

+0

@BoundaryImpositionパスタエラーをコピーします。固定 – NathanOliver

1

std::stringには、暗黙のconst char *変換コンストラクタがあります。

は、コンパイラは型が一致させるために暗黙の型変換を行うことを許可されているので、ctorのはstd::string一時的にconst char *を変換すると使用しており、それが結合させるそこからconst&(のconst左辺値参照)ので、順風満帆です一時的に(そして寿命を延ばす)。

4

文字列リテラルに変換され、「こんにちは」、

用語「変数」はかなり漠然と定義されている変数ではありません、本当にバックアップされません具体的なコンセプトで

"hello"は、変更できない静的記憶期間を持つオブジェクトを表します。他の式と同様に、他のオブジェクトを初期化するために潜在的に使用される可能性があります。この場合、std::stringを式(const char*に減衰した後)で初期化しています。

あなたが欠けているのは、 "中間ステップ"です。一時的にそのリテラルから一時的にstd::stringを作成し、その生涯をバインディング経由でref-to-constに拡張します。

ので、ISH:詳細については、およそ暗黙的変換を読む

const std::string temp{"Hello world"}; // the compiler creates this transparently 
const std::string& ref = temp; // this is yours, and it extends temp's life 

関連する問題