• 締切済み

const 回りのエラー?

以下のプログラムをcygiwn 上でコンパイルすると エラーが出るのですが 何がいけないのかよくわかりません。 メッセージを読んでconst 回りなのかな?とは思っているのですが… よろしくお願いします。 #include<iostream> #include<cstring> #include<cstdlib> using namespace std; class sample{ char *s; public: sample(); sample(const sample &ob); ~sample(){if(s) delete [] s; cout << "Freeing s\n";} void show(){cout << s << "\n";} void set(char *str); sample operator=(sample &ob); }; sample::sample() { s = new char('\0'); if(!s){ cout << "Allocation error\n"; exit(1); } } sample::sample(const sample &ob) { s = new char[strlen(ob.s)+1]; if(!s){ cout << "Allocation error\n"; exit(1); } strcpy(s,ob.s); } void sample::set(char *str) { s = new char[strlen(str)+1]; if(!s){ cout << "Allocation error\n"; exit(1); } strcpy(s,str); } sample sample::operator=(sample &ob) { if(strlen(ob.s)>strlen(s)){ delete [] s; s = new char[strlen(ob.s)+1]; if(!s){ cout << "Allocation error\n"; exit(1); } } strcpy(s,ob.s); return *this; } sample input() { char instr[80]; sample str; cout << "Enter a string: "; cin >> instr; str.set(instr); return str; } int main() { sample ob; ob = input(); ob.show(); return 0; } <コンパイル結果> In function 'int main()': 78:error:no match for 'operator=' in 'ob = input()()' 49:note:candidates are: sample sample::operator=(sample&)

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

単に「だめだった」というのではなく, どのようなエラーメッセージが出たのかも書くようにしてください. 手元では (Cygwin じゃないけど g++ で) #1 の修正で (つまり引数を const sample & にするだけで) 問題なくコンパイルできましたよ. 定義するところを修正し忘れているとかいうオチはないだろうなぁ.... あと, ついでにいうと sample::set でリークしますね.

回答No.2

ob = input(); 一時オブジェクトの参照渡しをやってますね。 sample ob; sample oa=input(); ob = oa; ならコンパイルできるのでは?(未確認)

rukusu
質問者

お礼

コンパイル通りました! ありがとうございます。 あとはご指摘いただいた内容を理解できるように ゆっくり読んでいきたいと思います(笑)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

代入演算子のオーバーロードを sample operator=(const sample &ob); にすればいいはず. もっとも, 普通は sample &operator=(const sample &ob); でしょうが. ついでにいうとデフォルトコンストラクタもなんかおかしい. あとで ::operator delete[] を使うので, s = new char[1]; *s = 0; のように ::operator new[] を使うのが本手だと思う.

rukusu
質問者

お礼

回答ありがとうございます。 ご指摘通りオーバーロードを記述してみたのですが だめでした。 別の方の回答で一応の解決は見たので デフォルトコンストラクタの部分は ゆっくり見て考えさせていただきたいと思います。 ありがとうございました。

関連するQ&A

  • C++のnew演算子で動的確保

    new()を初めて使ってみました。 エラーは無かったけど、間違いがあったら教えてください。 #include <iostream.h> main(){ int n = 0; char* str = "mojisuufumei"; char* myValue; while(!str[n])n++; myValue = new char[n+1]; strcpy(myValue, str); cout << myValue; delete []myValue; } char*型のmyValueを動的確保したつもりです。 myValue[0], myValue[1], … のそれぞれの値を unsignedにして宣言したい場合はどうしたらいいんですか? #include <iostream.h> main(){ int n = 0; char* str = "mojisuufumei"; unsigned char* myValue; while(!str[n])n++; myValue = new unsigned char[n+1]; strcpy(myValue, str); cout << myValue; delete []myValue; } だと、strcpy()のとこでコンパイルエラーでした。

  • 文字列の扱いについて教えてください

    #include<cstdio> #include<cstring> #define _CRT_SECURE_NO_DEPRECATE 1 #define MAXBUFF 256 void s_swap(char* str_a, char* str_b) { char str_dummy[MAXBUFF]; strcpy_s(str_dummy,strlen(str_dummy),str_a); ★ strcpy_s(str_a,strlen(str_a),str_b); ★ strcpy_s(str_b,strlen(str_b),str_dummy); } void main(void) { char* str_a = "ABC"; char* str_b = "DEF"; int a; printf("呼出前:str_a=%s, str_b=%s\n", str_a, str_b); s_swap(str_a,str_b); printf("呼出後:str_a=%s, str_b=%s\n", str_a, str_b); } str_aとstr_bの中身を入れ替える処理で、エラーや警告はでないのですが ★のところで実行失敗します。 昔から文字列の処理は苦手でどのように攻略したらよいのか 解説していただけないでしょうか。

  • プロンプト入力 malloc( )

    #include <iostream.h> void f(char* str); main(){ char s[8] = "\0"; cout << "文字を入力" << '\n'; fgets(s, 8, stdin); f(s); } void f(char* str){ char* c; c = (char*)malloc(sizeof(char) * strlen(str)+1); cout << strlen(str) << '\n'; cout << sizeof(c); free(c); } - 結果 - 文字を入力 ( a、Ctrl+Z ) a 1 4 でした。 cout << sizeof(c); の結果は4でした。1バイトの入力だから\0を含めて 2バイトを確保したかった。 そのためにはどうしたらいいんですか? どうして4だったんですか? 文字を入力するとこで、Ctrl+Z の代わりに Enter を押すと Enter まで s に格納されてしまう。 cin を使うと8バイト以上の入力でも s に格納されてしまう。 そうならないためのよい方法があったら教えてください。

  • 文字列クラスを作りたいと思っています。-2

    文字列クラスを作りたいと思っています。 以下のようなところまでは作れましたが、 エラーがでてしまいます。 どこかおかしいところがあるのでしょうか? ********************************************** #include<stdio.h> #include<string.h> #include<conio.h> class stt { public: char *str; int len; bool maked; stt::stt() { len=0; str=NULL; maked=false; } stt::~stt() { delete[] str; } stt &operator =(char *c) { if(maked) { delete[] str; maked=false; } len=strlen(c); str=new char[len+1]; strcpy(str,c); maked=true; return (*this); } stt &operator =(stt &ste) { if(maked) { delete[] str; maked=false; } len=strlen(ste.str); str=new char[len+1]; strcpy(str,ste.str); maked=true; return (*this); } stt operator +(stt ste) { static stt tet; int len1=strlen(str); int len2=strlen(ste.str); tet.str=new char[len1+len2+2]; strcpy(tet.str,str); strcat(tet.str,ste.str); tet.str[len1+len2+1]='\0'; return tet; } virtual operator char*() { return str; } }; int main() { stt ss,ww,pp; pp="Hello"; ss="Nice to meet you.\n"; ww="I am studing Visual C++"; pp=ss+ww; printf(pp); getchar(); return 0; } **********************************************

  • operator +()について

    --------------------------------------- 文字列クラスを作りたいと思っています。 以下のようなところまでは作れましたが、 全てのstrをdelete[] str;しているのかわかりません。 delete[] str;を確認するにはどうすればいいですか? --------------------------------------- #include<stdio.h> #include<string.h> #include<conio.h> class stt { public: char *str; int len; bool maked; stt::stt() { len=0; str=NULL; maked=false; } stt::~stt()// ちゃんとデストラクタ内で、全てのstrがdeleteされているのでしょうか? { if(maked) { delete[] str; } else { maked=true; } } stt &operator =(char *c) { if(maked) { delete[] str; maked=false; } len=strlen(c); str=new char[len+1]; strcpy(str,c); maked=true; return (*this); } stt &operator =(stt &ste) { if(maked) { delete[] str; maked=false; } len=strlen(ste.str); str=new char[len+1]; strcpy(str,ste.str); maked=true; return (*this); } stt operator +(stt ste) { stt tet; int len1=strlen(str); int len2=strlen(ste.str); tet.str=new char[len1+len2+2]; strcpy(tet.str,str); strcat(tet.str,ste.str); tet.str[len1+len2+1]='\0'; ste.maked=false;//不安部分 return tet; } virtual operator char*() { return str; } }; int main() { stt ss,ww,pp; ss="a"; ww="b"; pp=ss+ww; printf(pp); printf("\n"); getchar(); return 0; }

  • 文字列クラスを作りたいと思っています

    文字列クラスを作りたいと思っています。 以下のようなところまでは作れましたが、 エラーがでてしまいます。 どこかおかしいところがあるのでしょうか? *********************************************** #include<stdio.h> #include<string.h> class stt { public: char *str; int len; bool maked; stt::stt() { len=0; str=NULL; maked=false; } stt::~stt() { delete[] str; } stt &operator =(char *c) { if(maked) { delete[] str; maked=false; } len=strlen(c); str=new char[len]; strcpy(str,c); maked=true; return (*this); } virtual operator char*() { return str; } }; int main() { stt s; s="Hello World"; printf(s); getchar(); return 0; } ***********************************************

  • 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++ : cout << (数字) で実行時エラーが発生する理由

    ある特定の位置でcout を用いて数字を表示しようとするとエラーが発生してしまいます。 具体的には以下の関数内でのことなのですが、原因の分かる方がいましたら解答お願いします。 受け取った文字列を逆順にする関数です。 ---------------------------------------------------------- void rev_str(char *a) { int length = 0; cout << length; // ここでエラーが発生 while(true) { if(*(a + length) == '\0') break; length++; } for(int i = 0; i < length / 2; i++) { char temp = a[i]; a[i] = a[length - i - 1]; a[length - i - 1] = temp; } } --------------------------------------------------------- エラーの発生する部分ですが、数字ではなく文字・文字列なら問題なく表示されます。 このコードでは変数 length を表示しようとしていますが、length でなくても、またどのような『数』でも『この関数内』で cout を使用するとエラーが発生します。 この関数に何か間違いがあるのではないかと思うのですが、どうにも見つけることが出来ません。 コード全体はこの下に掲載します。 cout に何か制約があるのでしょうか。それとも、やはりコードのどこかに誤りがあるのでしょうか。わかる方がいましたら、解答お願いします。 全コード ------------------------------------------------------ #include <iostream> #include <cstring> using namespace std; void rev_str(char *a); void rev_str(const char *source, char *des); int main() { char a[80], b[80]; strcpy(a, "hello, world!"); rev_str(a, b); rev_str(a); cout << a << "\n"; cout << b << "\n"; return 0; } void rev_str(char *a) { int length = 0; cout << length; while(true) { if(*(a + length) == '\0') break; length++; } for(int i = 0; i < length / 2; i++) { char temp = a[i]; a[i] = a[length - i - 1]; a[length - i - 1] = temp; } } void rev_str(const char *source, char *des) { char *a = (char*)malloc(sizeof(source)); strcpy(a, source); rev_str(a); strcpy(des, a); free(a); }

  • C言語でセグメンテーションエラーの原因がわからず困っています。

    こんにちは。いつもお世話になっております。 C言語なのですが、何故かプログラムを実行するとセグメンテーション違反が表示されてしまい全く動きません。皆さんのお力を貸して頂けないでしょうか。 以下が問題のプログラムです。 前提条件: ・別プログラムによりfile.txtは末尾に文章が追加され続けている ・本プログラムは永劫的に動き続ける #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<errno.h> #include<signal.h> #include<sys/types.h> int main () { int i = 1, a; FILE *fp, *fp2; char *tok; //NULLを入れて初期化 char buf[1024] = ""; char str[1024] = ""; char str2[1024] = ""; //出力するファイルを開く if ((fp2 = fopen ("out.txt", "a")) == NULL) { printf ("out.txt:open error\n"); exit (-1); } while (1) { //何度もfopenするのでループ二週目以降は一旦fpを閉じる if (str2 != NULL) { fclose (fp); } //一度読み込み、2週目以降もさらに読み込み続ける if ((fp = fopen ("file.txt", "r")) == NULL) { printf ("file.txt:open error\n"); exit (-1); } //str2はループ2週目以降で使われる if (str2 != NULL) { while (1) //新しい行を見つけ出す { fgets (str, 1024, fp); if (strstr (str, str2) != NULL) { printf ("前回の最終行です:%s\n", str); break; } } } else { printf ("str2はNULLです:%s\n", str2); } //fopenで読み込んだ現段階のテキストファイルをout.txtに移す while (1) { if( (fgets (str, 1024, fp) ) == NULL)break; if ((a = strlen (str)) >= 2) { str[a - 1] = '\0'; } else { printf ("抽出した文字列が1文字以下です:%s\n", str); break; } if (strlen (str) >= 17) { strcpy (str2, str); } else { printf ("抽出した文字列が16文字以下です:%s\n", str); break; } printf ("%s\n", buf); fprintf (fp2, "%s\n", buf); strcpy (buf, ""); strcpy (str2, str); } printf ("これが検索語です:%s\n", str2); } fclose (fp2); return 0; } プログラムの内容は、 更新され続けるテキストファイル(file.txt)から、別のテキストファイル(out.txt)に出力するというプログラムです。(file.txtの内容を若干変えつつ、out.txtに出力することが本来の目的ですが、その部分は省略させて頂きました。) fopenで開くと、「その時点まで」のfile.txtしか開かれません。更新され続けているfile.txtの内容をコンスタントに読み取る為に、while文でfopenし続ける方法を取っていますが、そうするとout.txtに移し終わった行まで読み込んでしまい重複した文章をout.txtに移すことになりますので、strstrを使い、「前回fopenで開いたfile.txt」の最終行を検索してその位置からまたout.txtに移す、という方法を取りました。しかし、結果は何故かセグメンテーション違反でした。 以上のプログラムや私の意図する所で何か気づかれた点や、おかしいと思われた点等ありましたら是非ご教授頂きたく思います。 どんな些細なことでも構いませんので、教えて頂けないでしょうか。 環境はCentosです。どうぞよろしくお願いします。

  • C言語の文字列の取り扱いが分かりません

    こんにちは。 C言語で分からないことがあり、質問させていただきました。 学校で、文字列の取り扱いを習いました。 そこで質問なんですが、以下のソースコードをstrcpy , strcat , strcmp , strlen を使わずに書くことってできないですか? 先生に質問したところ、ポインタとかいうのを使うのだそうですが、それを使わずに書くことってできるんですか?もしよろしければお願いします。 以下のプログラムですが、ユーザーから2つの文字列を受けて、そこから4つの文字列関数を使ってみましょう、というやつです。実行結果も貼っておきますね。 #include <string.h> #include <stdio.h> int main(void) { char str1[80], str2[80]; int i; printf("INPUT 1st word-line. : "); gets(str1); printf("INPUT 2nd word-line. : "); gets(str2); /*文字列(word-line)の長さを確認します。*/ printf("%s is %d moji long.\n", str1, strlen(str1)); printf("%s is %d moji long.\n", str2, strlen(str2)); /*文字列を比較します。*/ i = strcmp(str1, str2); if (!i) printf("two word-lines are same length.\n"); else if (i < 0) printf("%s is smaller than %s.\n", str1, str2); else printf("%s is bigger than %s.\n", str1, str2); /*十分なスペースがあるのなら、str2をstr1の最後に結合させます。*/ if((strlen(str1) + strlen(str2)) < 80 ){ strcat(str1, str2); printf("%s\n", str1); } /*str2をstr1にコピーする*/ strcpy(str1, str2); printf("%s %s\n", str1, str2);

専門家に質問してみよう