2017-02-24 8 views
3

私は次の問題があります。以下のコードでは、オブジェクト変数pのアドレスは、最初のメンバー 'a'のアドレスと同じです。しかし、私はpとaの値を両方とも表示します。どのように同じ住所の場所に2つの異なる値がありますか?同じアドレスの場所はどのように2つの異なる値を与えますか?

class sample { 
public: 
    int a; 
    int b; 
    int c; 

    //sample(); 
    sample(int x,int y, int z){ 
     a=x; 
     b=y; 
     c=z; 
    }  

}; 


int main() { 
    //sample p; 
    //sample sample(2,3,4); 
    sample p = sample(2,3,4); 
    // cout<<"The value that is stored in the z is "<< p <<endl; 
    printf("The value of the object handle p is %d \n",p); 
    printf("The address of the object handle p is %d \n",&p); 
    //p->a =2; 
    //p->b =3; This could be accessesd in the later part of the code. 
    //p->c =4; 

    printf("The address of a is %d\n",&(p.a)); 
    printf("The value stored in the a is %d\n",p.a); 
    printf("The value stored in the b is %d\n",p.b); 
    printf("The value stored in the c is %d\n",p.c); 
} 

上記のコードの出力は次のとおり

The value of the object handle p is 2358832 
The address of the object handle p is 2358848 
The address of a is 2358848 
The value stored in the a is 2 
The value stored in the b is 2358852 
The value stored in the c is 2358856 

-------------------------------- 
Process exited after 0.2105 seconds with return value 0 
Press any key to continue . . . 
+0

通常、最初のprintfは実行時エラーを引き起こします。コンパイラは、途中でコンパイルしながらそれぞれの警告を出す必要があります。 – dmi

+1

あなたは仮定が偽です。第1の 'printf'は期待どおりに動作しません。 (オブジェクトpをスタックに置き、最初の 'sizeof(int)'バイトを 'int'値として読み込みます)' printf'は可変引数を使用しますが、**型安全ではありません。代わりに 'std :: cout'でこれを試してください。それで、それはおそらくコンパイルされません。 ( 'sample'クラスの出力演算子がないためです。) – Scheff

+0

いいえ、コンパイルエラーは発生しませんでした。ターミナルからの出力をそのまま貼り付けました。ところで、私はdev C++を使用しており、コンパイラはTDM-GCC 4.9.2 64ビットリリースです。 –

答えて

4

printfは、可変長引数を使用します。しかし、gccの拡張機能がフォーマット文字列に対するバリデーション引数をチェックするのを見ましたが、実際には文字列をフォーマットする引数のタイプマッチについて実際にコンパイル時間チェックはありません。

したがって、printfはC++では使用しないでください。型安全な代替はストリームです。

ストリーム演算子(実際にはこれらはオーバーロードされたシフト演算子です)は、標準ライブラリの特定のクラス(たとえば、std::string)と組み込み型で使用できます。

自己設計クラスのストリーム出力をサポートするには、ストリーム出力演算子をオーバーロードする必要があります。例えば:

#include <iostream> 

class Sample { 
    friend std::ostream& operator << (std::ostream&, const Sample&); 
    private: 
    int _a, _b, _c; 
    public: 
    Sample(int a, int b, int c): _a(a), _b(b), _c(c) { } 

}; 

std::ostream& operator << (std::ostream &out, const Sample &s) 
{ 
    return out << s._a << ", " << s._b << ", " << s._c; 
} 

int main(int, char**) 
{ 
    Sample sample = Sample(123, 234, 345); 
    std::cout << "sample: " << sample << std::endl; 
    return 0; 
} 

コンパイルとCygwinのgccでテストした:私はfriendを行った場合、ストリーム出力オペレータはそれらにアクセスすることを実証するためにa, b, cprivateを作った

$ g++ -std=c++11 -o test-cout test-cout.cc 

$ ./test-cout 
sample: 123, 234, 345 

関連する問題