C++のコンストラクタを使った自動ポインタでoperator関数の使い方について

このQ&Aのポイント
  • C++のコンストラクタを使った自動ポインタでoperator関数の使い方で分からないところがあります。
  • C++のコンストラクタを使用した自動ポインタでoperator関数を配列のように扱う際に実行エラーが発生します。
  • コードの実行中に、operator関数の書き方の問題や原因を特定することができません。
回答を見る
  • ベストアンサー

C++のコンストラクタを使った自動ポインタでoperator関数の使い

C++のコンストラクタを使った自動ポインタでoperator関数の使い方で分からないところがあります。 環境下はVisual C++でC/C++のWin32コンソールアプリケーションを使って行っています。 下記のコードで実行させています。やっていることは文字列を反転させて表示させるだけのことです。 #include "stdafx.h" #include <string> #include <iostream> class AutoPtr { char *ptr; public: AutoPtr():ptr(0) { } ~AutoPtr() { delete [] ptr; } // char *operator=(char *ptr) { delete [] this->ptr; this->ptr = ptr; return this->ptr; } operator char *(){ return ptr; } char &operator[](int index) { return ptr[index]; } }; void reverse(char *str) { int i, n; AutoPtr work; n = strlen(str); work = new char[n+1]; strcpy(work, str); for(i=0; i<n; i++) { str[i] = work[n-i-1]; } printf("%s\n", str); } int _tmain(int argc, _TCHAR* argv[]) { reverse("ABCDEFG"); return 0; } これを実行させると、reverse関数のfor()文の、str[i] = work[n-i-1];を実行させた所で実行エラーになってしまいます。その前の、strcpy(work, str);でworkにstrの内容が正常にコピーされているところまでは確認できています。operator関数の、 char &operator[](int index) { return ptr[index]; } で、operator[]はAutoPtrを配列のように扱っているはずなのですが、何故かstr[i] = work[n-i-1]; の所で実行エラーになってしまいます。 operaror関数の書き方が悪いのか、何が原因なのか分かりかねています。御経験のあるかたは、御教示いただけたらと思っています。 よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

ポインタ変数strは何をさしていますか? reverse関数のパラメータだから、"ABCDEFG"という文字列リテラルの先頭ポインタですよね。 文字列リテラルは定数値です。書き換えることは出来ません。

tmiyoshi
質問者

補足

reverse("ABCDEFG")は、 char *str = "ABCDEFG"; reverse(str); と同じで駄目のようです。 char str[] = "ABCDEFG"; reverse(str); とするとOKのようです。(文字型配列へのポインタとしてstrを定義する) ありがとうございました。

関連するQ&A

  • C++のoperator関数でのキャストする場合の書き方がまだよく理解

    C++のoperator関数でのキャストする場合の書き方がまだよく理解できていません。 下記のコードで、 //ここから #include "stdafx.h" #include <string> #include <iostream> class AutoPtr { char *ptr; public: AutoPtr():ptr(0) { } ~AutoPtr() { delete [] ptr; } // char *operator=(char *ptr) { delete [] this->ptr; this->ptr = ptr; return this->ptr; } operator char *(){ return ptr; } char &operator[](int index) { return ptr[index]; } }; void reverse(char *str) { int i, n; AutoPtr work; n = strlen(str); work = new char[n+1]; strcpy(work, str); for(i=0; i<n; i++) { str[i] = work[n-i-1]; } printf("%s\n", str); } int _tmain(int argc, _TCHAR* argv[]) { char str[] = "ABCDEFG"; reverse(str); return 0; } //ここまで 2番目のoperator関数の定義ですが、 operator char *(){ return ptr; } これは多分、reverse()関数中の、 strcpy(work, str); のworkの展開に用いられると思うのですが、 機能としては、「operator char *」はAutoPtrをchar *にキャストするために使われているらしいのですが、何故この書き方でAutoPtrをchar *型にキャストできるのかがいまいち分かりません。また、2番目のoperator関数の記述「operator char *()」はどこまでが型で、どこからが関数の定義と見なせばよいのでしょうか? 何か勘違いしているかもしれません。理解されている方、御教示いただければと思っています。 よろしくお願い致します。

  • C言語の、ポインターの問題を教えて下さい

    C言語の、ポインターを使って大文字と小文字を入れ替えるプログラムを教えて下さい。 作ったのですが、うまくいかず困っています。 分かる方、訂正してください。 よろしくお願いいたします。 #include<stdio.h> void reverse(char *str) { int i; for(i=0;str[i]!='\0';i++) { if(str[i]>=0x61) {str[i]-0x20;} if(0x40<str[i]<0x5B) {str[i]+0x20;} } return(str); } int main(void) { int num; char *str="AddsssEEEEwwwJojoHoih"; printf("Before reverse %s \n",str) str=reverse(str); printf("After reverse %s \n",str); return 0; }

  • [C]char型のダブルポインタ

    粗雑で申し訳ありませんが、 以下のソースをコンパイルできましたが、 うまく実行できません。 自分なりに間違いがないと思うのですが、 間違い等をご指摘頂ければ助かります。 #include <stdio.h> void func(char **ptr) ptr[][10] か (*ptr)[] なら通る *ptr[] は通らない { printf("----- func -----"); printf("%s\n", *ptr); printf("%c\n", **ptr); putchar('\n'); } int main(void) { char str[5][10] = {"AAAAA", *str[] にすると func で **ptr で通る "BBBBB", "CCCCC", "DDDDD", "EEEEE", }; printf("----- main -----"); printf("%s\n", *str); printf("%c\n", **str); putchar('\n'); func(str); return (0); } 実行結果 ----- main ----- AAAAA A ----- func ----- Bus error (core dump) 関数への受け渡しで、型が違うというお叱りを受けますが、 コンパイルはできました。 コンパイラはCCです。 ではよろしくお願いします。

  • abcdとキーボードで打ったらdcbaと表示されるプログラム

    C言語に関しては初心者です。 メイン関数は変更せずに行います。 /* reverse.c: reverse a given string */ #include <stdio.h> #include <string.h> void reverse(char *); /* プロトタイプ宣言 */ int main(void) { char str[100]; scanf("%s", str); reverse(str); printf("%s\n", str); return (0); } void reverse(char *s) { char n; int i; char str; n = strlen(str) - 1; for(i=0,i++,i<=100) { s[i] = *s[n-i]; printf("%s\"s[i]); } }

  • 文字の並べ替え

    C言語で文字の並べ替えをしたいのですが条件があり ポインタを使って文字を並べ替える別の関数をを渡さなければなりません.(void reverse(char *str)をつくる) そこで作ったのが #include <stdio.h> #include <string.h> void reverse(char *str); int main(void){ char s[80]; gets(s); reverse(s); printf("%s\n",s); return 0; } void reverse(char *str){ char q[80]; int i,n; n=strlen(str)-1; str+=n; for(i=0;i<=n;i++)q[i]=*str--; str++; q[i]='\0'; for(i=0;i<=n;i++)*str++=q[i]; } なのですが ポインタを使っている意味が余りないので ポインタを使うよりよいプログラムを教えてください. (アドバイスでもかまいません.)

  • C言語 文字列操作

    トリム関数とリムーブ関数を作成してみました。改良点はありますでしょうか? ~~~~以下ソース~~~~ #include <stdio.h> #include <stdlib.h> #include <string.h> char *Trim(char *str); char *Remove(char *str, char *rmv); void main(void) {  char str[10], rmv[10], *p;  int c;  /* " abcd "をトリムする */  strcpy(str, " abcd ");  printf("トリム前 |%s|\n", str);  p = Trim(str);  printf("トリム後 |%s|\n", str);  /* 指定文字列を削除する */  printf("削除する文字列を入力してください :");  scanf("%s", rmv);  Remove(str, rmv);  printf("削除後 |%s|\n", str);  exit(0); } char *Trim(char *str) {  char space[] = " ";  char null[] = "";  int index = 0;  while(1){   if(strcmp(&(str[index]), null) == 0){    index--;    if(strncmp(&(str[index]), space, 1) == 0){     strcpy(&(str[index]), &(str[index]) + 1);    }else{     break;    }   }else{    if(strncmp(&(str[index]), space, 1) == 0 && index == 0){     strcpy(&(str[index]), &(str[index]) + 1);    }else{     index++;    }   }  }  return str; } char *Remove(char *str, char *rmv) {  int c, size, i;  char *p;  c = '\0';  p = strchr(rmv, c);  size = p - rmv;  for(i = 0; i < size; i++){   c = (int)rmv[i];   p = strchr(str, c);   if (p != NULL) {    strcpy(&(str[p-str]), p + 1);   }   else{    printf("""%c""は見つかりませんでした\n", c);   }  }  return str; }

  • for文

    以下のプログラムのforの条件文がなぜこれで動くのかよくわからないので 教えていただけないでしょうか? #include<stdio.h> int main(void) { int i; char str[] = "ABC"; char *ptr = "123"; for(i=0;str[i];i++) putchar(str[i]); putchar('\n'); for(i=0;ptr[i];i++) putchar(ptr[i]); putchar('\n'); printf("str = \"%s\"\n",str); printf("ptr = \"%s\"\n",ptr); return(0); }

  • ポインタ代入のoperator演算子のオーバロードの仕方

    下記、unsigned char*型を自前のクラスで作成した場合 どの様なoperator演算子が必要になりますでしょうか。 目的は、下記compにアクセスした回数をカウントさせたい為です。オーバロード関数の内部にカウンタを持たせたい。 unsigned char* と互換性を持たせるため、クラスはポインタとして定義して使用したいと思っています。 unsigned char comp[1000] ; int main( int, char** ){ unsigned char *v_ptr ; v_ptr = &comp[0] ; <- ここ *v_ptr = (unsigned char)100 ; <- ここ *v_ptr++ = *sw_ptr++ ; <- ここ return 0; } 下記のように使いたい unsigned char comp[1000] ; int main( int, char** ){ count * v_ptr ; v_ptr = &comp[0] ; <- ここ *v_ptr = (unsigned char)100 ; <- ここ *v_ptr++ = *sw_ptr++ ; <- ここ return 0; } class count{ public: unsigned char* operator*() { return ptr ; }  v_ptr& operator=()?? private: unsigned char* ptr ; } ; 色々調べてみましたが、自前クラスが右辺にある時のポインタ、アドレスオーバロードはありましたが、左辺のポインタ代入、値代入を見つける事が出来ませんでした。

  • 教えてください

    入力した文字列のスペースをすべて取り除く関数を返すのですが、分かりません。(例)a s d fと入力したら、asdfと表示します。途中まで考えたのですが、どうしてもできません。教えてください。宜しくお願いします。(このソースは、コンパイルエラーです。) 14: 移植性のないポインタ変換(関数a) #include <stdio.h> char a(char *st) { char *ptr=st; while(*st!='\0') { if (*st != ' ') { *ptr++=*st; } } *ptr='\0'; return(ptr); } int main(void) { char str[21]={'\0'}; int i=0; char ch; printf("文字列を入力してください:"); while(i<21) { ch=getchar(); if (ch=='\n') {break; } else if (ch != '\0' && ch != '\n') { str[i] =ch; i++; } } str[i] = '\0'; printf("%s",a(str)); return(0); }

  • C++ operatorの使用について

    C++初心者で、現在オペレーターの使用方法について勉強しています。 下記プログラムの「 x = x + z;」箇所の処理について、理解できず行き詰っています。 初期化した際のx, y, zそれぞれの値が x = Help y = !e z = M となったところまでは、理解できています。 その後、x = x + zの処理に入る際、 1.abc operator+(abc) 2.void operator=(abc) の順でオペレーターの処理を行うと思います。 その際、1.はzを使用して処理をするところまでは分かるのですが、 return value: HelpM\n(\:バックスラッシュ)がx, y, zのどこに入るのか、 その後どのオブジェクトを持って2.の処理に入るのかどうか 理解できておりません。 初心者のため、文章がわかりづらい点等あるかと思いますが、 アドバイス頂けたら幸いです。 宜しくお願いいたします。 ========================================================================== #include <cstdio> #include <cstring> class abc { char def[21]; public: abc(void) { strcpy(def, "Help"); } abc(const char s[ ]) { strcpy(def, s); } abc(char c) { def[0] = c; def[1] = '\0'; } void operator=(abc); // redefines = between abc's!!! abc operator+(abc); void out( ) { printf("%s\n", def); } }; void abc::operator=(abc x) { int i, n = strlen(x.def); for(i = 0; i < n; i++) def[i] = x.def[n - (i + 1)]; def[n] = '\0'; } abc abc::operator+(abc a) { int i = 0; abc c; strcpy(c.def, def); while(c.def[i] != '\0') i++; for(int j = 0; a.def[j] != '\0'; j++) { c.def[i] = a.def[j]; i++; } c.def[i] = '\0'; return c; } int main( ) { abc x, y("!e"), z('M'); x = x + z; x.out( ); y = y + x; y.out( ); return 0; }

専門家に質問してみよう