9

私はc++の参照を研究していますが、変数名と参照の違いにかなり混乱しています。テストコードは以下のとおりです。

class TestClass{
private:
    int num;
public:
    TestClass(int n):num(n){
        cout<<this<<" : init of : " <<this->num<<endl;
    }

    TestClass(const TestClass& t):num(t.num){
        cout<<this<<" : copyInit of : " <<this->num<<endl;
    }

};

int main(int argc, const char * argv[]){

    TestClass t = *(new TestClass(55)); //just to test copy initialization

    const TestClass t2 = TestClass(100); //option1
    const TestClass &t2 = TestClass(100); //option2


}

だから今、私はオブジェクトを作るのに2つのオプションがあります。それらは互いに排他的です。

私の理解では、options2を使用すると、コンパイラはスタックメモリに一時オブジェクトを作成し、参照値をt2に返します。

これが正しい場合、オプション1を言葉で表現または説明するにはどうすればよいですか?同じオブジェクトがスタックメモリに作成され、コンピュータがそのオブジェクトに「t2」という名前を付けているようですが、変数の名前と参照がやや紛らわしいため、このoption1とoption2の違いがはっきりとわかりません。

さらに、オプションを切り替える代わりに、オブジェクトがそれぞれ異なるメモリ位置に作成されていることがわかりました。(たとえば、option1のオブジェクトは0x7fff5fbff828で作成され、それまたはoption2は0x7fff5fbff820にありました)

説明してもらえますか

1.変数名(option1)と参照(option2)の違いは何ですか。

2.オプション1と2での動作の違い。

3.どちらの場合でも、オブジェクトが異なるメモリ位置に作成される理由。

よろしくお願いします!

4

2 に答える 2

3
const TestClass t2 = TestClass(100); //option1
const TestClass &t2 = TestClass(100); //option2

オプション1:

TestClassのコピーコンストラクターを呼び出し、「=」の右側に作成された一時的なものを渡します。コピーの省略により、オブジェクトの不要なコピーが排除されます(以下のPiotrsのコメントを参照)。

オプション2:

参照にバインドされる一時的なオブジェクトを1つ作成します。

  1. 変数名(option1)と参照(option2)の違いは何ですか。

編集:これは以前は知りませんでしたが、実際にはオプション1に2番目の割り当てはありません(Piotrに感謝)。これは、オブジェクトの不要なコピーを排除するコンパイラ最適化手法を参照するコピーの省略によるものです。

あなたの言葉を使うために、「変数名」はデータを含むメモリのブロックです。参照は、別の「変数名」を指すという意味ではポインターに似ていますが、初期化する必要があり、nullになることはありません。

  1. オプション1と2での動作の違い。

他の人が言っているように、オプション1は静的タイプであり、オプション2は(TestClassからの)派生オブジェクトのインスタンスを指すことができます。

  1. どちらの場合でも、オブジェクトが異なるメモリ位置に作成される理由。

「同一の」TestObjects(100)であるにもかかわらず、それらは個々のインスタンスであるため、異なるメモリ(アドレス)にあります。

于 2012-11-03T23:30:43.463 に答える
1

1)変数名(option1)と参照(option2)の違いは何ですか。

名前は静的タイプです。参照は派生クラスにバインドできます-参照されるオブジェクトの正確なタイプはわかりません。

あなたの例では、オプション2の場合、一時オブジェクトへのconst参照を作成することにより、一時オブジェクトの存続期間を延長しました。http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-を参照してください。最も重要なconst/

通常、一時オブジェクトは、それが現れる完全な式の終わりまでしか持続しません。ただし、C ++は、一時オブジェクトを参照にバインドしてスタック上のconstにバインドすると、一時オブジェクトの有効期間が参照自体の有効期間まで長くなることを意図的に指定しているため、一般的なぶら下がり参照エラーを回避できます。


2)オプション1と2で物事がどのように異なるか。

仮想関数を呼び出す場合(変数名の場合、どの関数が呼び出されるか、参照の場合)、より複雑な例ではわかりません。


3)どちらの場合でもオブジェクトが異なるメモリ位置に作成される理由。

それらは異なるオブジェクトであり、同時に存在します-それでは、なぜそれらのメモリ位置は同一でなければならないのですか?

その他の違いは、オプション1の場合は自動変数を作成し、オプション2の場合は一時変数であるということです。どちらも異なるメモリを使用する可能性があります(スタックとレジスタ、または一時的なメモリのみ)


より複雑な例を考えてみましょう。

class TestClass{
protected:
    int num;
public:
    TestClass(int n):num(n){
        cout<<this<<" : init of : " <<this->num<<endl;
    }
    TestClass(const TestClass& t):num(t.num){
        cout<<this<<" : copyInit of : " <<this->num<<endl;
    }
    virtual void printNum () const { cout << "NUM: " << num << endl; }
};

class TestClassDerived : public TestClass {
public:
    TestClassDerived(int n):TestClass(n){}
    virtual void printNum () const { cout << "DERIVED NUM: " << num << endl; }
};


int main(int argc, const char * argv[]){
    const TestClass t1 = TestClass(100); //option1
    const TestClass &t2 = TestClassDerived(100); //option2
    t1.printNum();
    t2.printNum();
}
于 2012-11-03T23:28:36.107 に答える