私は現在、C++を入門書を片手に独学しておりまして、いずれはゲームも作りたいと考えております。
プログラミング自体は勉強し始めて一ヶ月未満で、文法も完全にマスターしていない初心者です。
入門書に書かれているポインタについての事柄が気になって、コードを書きましたが予想に反した結果になってしまいました。
下記のようなコードを書いて色々と動作を試しておりました。お聞きしたいことは二つあります。
#include <cstdio>
using namespace std;
class Mystr{
private:
char* text;
int get_Leng(char *s){ //文字配列の長さを取得
int n = 0;
while (*s){
printf("get_Leng %d : sのアドレスは \" %d \" です 値は \' %c \' でした\n", n,s,*s); //内容確認用
++s;
++n;
}
return n;
}
void arr_Copy(char *s){ //文字配列の内容をコピー
for(int n=0; *(text+n) = *s; n++){
printf("arr_Copy %d : sのアドレスは \" %d \" です 値は \' %c \' でした\n", n,s,*s); //内容確認用
++s;
}
}
public:
Mystr(char* ss = "");
Mystr(const Mystr& obj);
~Mystr(){delete[] text;}
};
Mystr::Mystr(char *ss){ //引数で指定された文字列をtextに確保
text = new char[get_Leng(ss)+1];
arr_Copy(ss);
printf("コンストラクタ : text(s1)のアドレスは \" %d \" です 値は \' %s \' でした\n",text,text); //内容確認用
}
Mystr::Mystr(const Mystr& obj){ //引数のオブジェクトの text をコピー
text = new char[get_Leng(obj.text)+1];
arr_Copy(obj.text);
printf("コピーコンストラクタ : text(s2)のアドレスは \" %d \" です 値は \' %s \' でした\n",text,text); //内容確認用
printf("コピーコンストラクタ : obj.text(s1)のアドレスは \" %d \" です 値は \' %s \' でした\n",obj.text,obj.text); //内容確認用
}
int main(){
Mystr s1("abcd");
Mystr s2 = s1; //オブジェクトをコピー
return 0;
}
配列の長さを取得するget_Leng関数に渡された、コンストラクタのss(元は文字列リテラルの先頭アドレス?)は、get_Lengの中で更新(++s)されて
ポインタが終端文字('\0')に向けられる。そしてget_Lengから戻り、arr_Copyに同じくssを渡しますが、このssは先程のget_Leng関数によってポインタが進められていて、
意図した通りに動かない(コピーコンストラクタの方も)と考えていたのですが実際には、ちゃんと文字列の内容をコピーできています。
私のイメージは以下のようなものだったんですが、
'a' → 'b' → 'c' → 'd' → '\0' の '\0' に向けられている為、インクリメントしても意図した通りにならない
しかし、どうも結果を見ていると違うようですし
このget_Lengとarr_Copyに渡される"char *ss"並びに文字列リテラル"abcd"は、それぞれ別物なのでしょうか?
それとも他に何か大変な勘違いをしてしまっているのでしょうか......
二つ目の疑問ですが、
コピーコンストラクタの仮引数にconstをつけていますが、処理の中でget_Lengとarr_Copyにメンバ変数を渡し、"++s"の部分でアドレスを更新しているように見えます。
const付きのオブジェクトのメンバ変数は値を変更できないと入門書にも書いているのですが、何故"++s"という式を記述できるのでしょうか?
初歩的質問という以前に、解釈自体が間違っているのだろうと私も感じてはいるのですが
調べてみても理解できなかったので、質問をさせて頂きました。
どなたか教えて頂けませんか?
[追記]
すいません、文章中の変数名を間違って書いておりましたので訂正いたしました。