質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

3回答

1147閲覧

データメンバの相対位置の謎

apa

総合スコア68

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/08/05 11:51

class A {
public:
int a;
int b;
};
int main()
{

int A::* p = &A::a; // Aのint型メンバへのメンバポインタpの宣言 cout << p << endl; p = &A::b; // Aのメンバaの相対アドレスを代入 cout << p << endl; cin.get();

}

http://thales.philos.k.hosei.ac.jp/c++/section4-5.html
上記のサイトを見て非静的メンバ変数もアドレスを保持していると知りました。
その内部のアドレスを見るためにいろいろやってみたのですがうまくいきません
また int p = new int() = cout << p 結果 アドレス なのに対して
int A::
p = &A::a;  = cout << p 1 になります
&をつけるとアドレスが出ますが1なのがそもそも謎です。また
アドレスは出ますが、int A::* p = &A::a;
int A::* p = &A::b; 変数の場所は違うはずなのに同じアドレスが出てきます。
以上2点どうしても謎がとけないとで力を貸していただけると幸いです
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

その場合の operator<< はメンバを指すポインタを受け入れるオーバーロードが用意されていないというのが直接的な理由です。

オーバーロード解決のルールはかなり複雑ですが原則としては型変換なしで型がマッチできるものがあればそれを使い、厳密にマッチするものがなく暗黙の型変換を使って型がマッチできるものが唯一であればそれを使います。 メンバを指すポインタから変換可能で operator<< で表示可能な型は bool なので bool に変換されてから表示するという過程を経ます。

投稿2020/08/05 12:52

SaitoAtsushi

総合スコア5466

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

メンバポインタの値を見たかったら次のようにすると見えるようです。

C++

1#include <iostream> 2#include <cstdio> 3using namespace std; 4 5class A { 6public: 7 int a, b; 8 //virtual ~A() {} 9}; 10 11void dump(void *vp) 12{ 13 void **p = (void **)vp; 14 printf("%p\n", *p); 15} 16 17int main() 18{ 19 cout << "siozef(int A::*) = " << sizeof(int A::*)<< endl; 20 21 int A::*p = nullptr; 22 dump(&p); 23 24 p = &A::a; 25 dump(&p); 26 27 p = &A::b; 28 dump(&p); 29}

nullptr で初期化しても 0 ではないし、
%p で表示しているので、g++ では、オフセット 0 が (nil) と表示されます。
virtual なメンバ関数が定義されていると、vtable へのポインタが先頭に
挿入されるので、a や b のオフセットも変わります。

投稿2020/08/05 15:23

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

apa

2020/08/09 10:38

返信ありがとうございます。 siozef(int A::*)  ←こちらの書き方が見たことがないもので中身を見たところ int型の4バイトがsizeofから出力されたのですが、 こちらは どういった立ち回りをするのでしょうか いいサイトが見当たらなかったのでお教えいただけたらと思います。
kazuma-s

2020/08/09 17:11

sizeof(int) や sizeof(int *) は見たことがあるけれど、sizeof(int A::*) は見たことがないということでしょうか? sizeof(型名) でその型のサイズ(バイト数)が分かります。int A::* はメンバポインタという型です。また、sizeof 演算子が返す値の型は size_t でこれは unsigned long または unsigned long long または unsigned int など、処理系(コンパイラ)によって異なるものですが、符号なしであることは間違いありません。だから int ではないでしょう。コンパイラが 32ビット版なら 4、64ビット版なら 8 が返ってくるでしょう。
apa

2020/08/10 07:44

すいません コンパイラ64 86ためしても同じ 4が出力されてしまいます。 あと自分の理解力不足なのですが、なぜ sizeof(int A::*)これが intであるのかがわからないです。(sizeof引数のA::*の左にあるint)
kazuma-s

2020/08/10 10:00 編集

int は型。sizeof(int) はその int型のサイズで 4。 int * はポインタ型。sizeof(int *) はその (int *)型のサイズで 4 か 8。 * の左に int があろうが、char があろうが、ポインタならそのサイズは 4 か 8。 int A::* はメンバポインタ型。sizeof(int A::*) はその (int A::*)型のサイズで 4 か 8。 sizeof演算子が返す値の型は size_t でこれは unsigned。そのサイズは処理系依存。 ポインタ型に対して sizeof演算子が返す値は 4 とか 8 という値なので int型に型変換しても値は失われない。 sizeof(char)が 1、sizeof(int) が 4、sizeof(double) が 8 でも、 sizeof(char *) は 4 か 8。sizeof(int *) は 4 か 8。sizeof(double *) も 4 か 8。 class A に char c; int i; double; というメンバがあったとすると、 sizeof(char A::*) は 4 か 8。sizeof(int A::*) は 4 か 8。sizeof(double A::*) も 4 か 8。 通常のポインタも、メンバポインタもそのサイズは 4 か 8。ただし、メンバポインタは特殊な事情によりその倍のサイズになることがあったような記憶がありますが、私の勘違いかもしれません。 ただし、昔の 8ビットCPU や 16ビットCPU では、ポインタのサイズは 2 でした。int のサイズも 2でした。
kazuma-s

2020/08/10 10:07

コンパイラは何ですか? cout << sizeof(int *) も cout <<sizeof(int A::*) も 4 ですか?
apa

2020/08/10 11:16

勉強不足でもうしわけありませんが、そもそもコンパイラってなんのことをさされていますでしょうか?
guest

0

正確には1ではなくtrueを表示しようとしています。

c++

1int main() 2{ 3 int A::* p = nullptr; 4 cout << std::boolalpha; 5 cout << 1 << endl; 6 cout << 0 << endl; 7 cout << p << endl; 8 p = &A::a; // Aのint型メンバへのメンバポインタpの宣言 9 cout << p << endl; 10 p = &A::b; // Aのメンバaの相対アドレスを代入 11 cout << p << endl; 12 13 p = NULL; 14 cout << p << endl; 15}

投稿2020/08/05 12:13

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問