C++言語のメンバ関数の中身と使い方

このQ&Aのポイント
  • C++言語のクラスのメンバ関数について詳しく知りたいです。特にstringクラスのMid(int start, int length)関数とoperator+関数について教えてください。
  • stringクラスのMid(int start, int length)関数は、指定した位置から指定した長さの部分文字列を返す関数です。operator+関数は、2つの文字列を連結する演算子です。
  • 詳しい解説やサンプルコードは、公式ドキュメントやC++の学習サイトなどを参考にしてください。C++のメンバ関数を理解することで、より効果的なプログラミングが可能になります。
回答を見る
  • ベストアンサー

C++言語 メンバ関数

何気なく使用しているクラスのメンバ関数、これの中身が実際どうなってるか知りたいです。大別して2種類に分かれますので以下の2つを 教えて下さい。また詳しく載っているサイトなどあれば教えて下さい。 1,stringクラスMid(int start,int length関数と operator関数+について class String{ char *p; char *q; public: //各定義 }; String String::Mid(int start,int length) const { // } String String::operator+(const String&s)const{ return String(p+s.q+s.p); } 最初の方はイメージもつかず、2つめのほうはポインタに ポインタを加えようとしましたとでます。 教えて下さい。

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

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

ちょっとと特殊なところはあるけど, 最終的な結果は「(メンバでない) 関数」と大して変わりません. 特に virtual でない関数は「this という隠れ引数を持った, メンバでない関数」と同じといっていいでしょう. たとえば, 上の String::Mid は概念的に String String_Mid(const String *this, int start, int length) { //.... } と全く同じ. 呼び出すときに str.Mid(start, len) とあったら String_Mid(&str, start, len) と変換されると思ってもいいでしょう. operator で定義されるユーザ定義演算子も本質は同じで, ただ「演算子として書いていても自動的に関数呼び出しに変換される」だけです. だからイメージとしては String String_add(const String *this, const String &s) { return String(this->p + s.q + s.p); } としたのと同じです. 「ポインタにポインタを加えようとしました」と出る理由は分かりますか?

kouharing
質問者

補足

理由はよくわかりません。。

その他の回答 (3)

  • BLK314
  • ベストアンサー率55% (84/152)
回答No.4

>2つめのほうはポインタにポインタを加えようとしましたとでます。 参照といっても、実体はポインタだからです。 String String::operator+(const String&s)const{ return String(p+s.q+s.p); のpはchar型へのポインタですね。(char *p;) sはString型への参照です(const String&s)が、 実体はString型へのポインタです。 だから "ポインタにポインタを加えようとしました" です。

参考URL:
http://sealsoft.jp/ptr_and_ref.html
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

this->p とか s.q とか s.p とかの型が String であると思った根拠を述べよ.

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

this->p とか s.q とか s.p の型ってなんだ.

kouharing
質問者

補足

Stringですか

関連するQ&A

  • ポインタ

    String String Mid(int start, int length) const { char *p="HelloWorld"; char s[100]; p+=start; for(int i=0;i<length;i++) { *s++=*p+;; } return s3; で++には左辺値が必要ですとでます。 stringクラスのMid関数を実装しているのですが start分ポインタを進めてlength取り出す関数なんですが ここまでは組んだのですが、うまくいきません。 どうすればうまくいきますか?

  • C++の問題で・・

    C++の問題で・・ 参考書に「簡易的な文字列クラスStringを作成せよ。」という問題があり作りました。 いかにそのコードを示します。今回の質問の内容に関係ないとおもうところや、インクルードなどは省かせていただきます。 環境は Visual studio 2008です。OSはXPです。 class String{     int len; //文字列の長さ     char *s; //文字列の先頭文字へのポインタ public:     String(const char *);     int length()const{return len;} //長さを求める     operator const char * ()const{return s;}     bool operator==(String &a)const{return strcmp(this->s, a);}     char *operator+(String&)const; }; char * String::operator +(String &a)const {     char *memory = new char[this->len + a.len + 1];     memory[0] = '\0';     return strcat(strcat(memory, this->s), a); } String::String(const char *p): s(const_cast<char *>(p)), len(strlen(p)){} String::String(const String &x) {     s = x.s;     len = x.len; } inline std::ostream& operator<<(std::ostream &s, String &x) {     return s << static_cast<const char *>(x); } int main() {     String a("My name is Paul");     String b("My name is Paul");     String c("My name");     String d(" is Paul");     cout << "a = " << a << "\n";     cout << "b = " << b << "\n";     cout << "c = " << c << "\n";     cout << "d = " << d << "\n";     cout << "a == b " << (a == b) << "\n";     cout << "a == c " << (a == c) << "\n";     cout << "c + d = " << (c + d) << "\n"; }     このようなプログラムなのですが、上記の char * String::operator +(String &a)const {     char *memory = new char[this->len + a.len + 1];     memory[0] = '\0';     return strcat(strcat(memory, this->s), a); } ところで、 memory[0] = '\0'; を除くと文字列を出力した結果をみると、先頭にいらない言葉が入っています。 僕の場合は x9My name is Paul と表示されます。文字化け・・ではないのですが、ゴミのようなものが・・ どうしてこのようなことが起こるか、どこでゴミが入ってしまうのか教えてほしいです。 稚拙なプログラムで申し訳ないです。 もし、間違っている場所や、もっと簡単にかけるようなところがあれば、ご指摘いただくとありがたいです。 よろしくお願いします!

  • c言語関数の(1)~(5)までの部分が何をやっているのかよく分からない

    c言語関数の(1)~(5)までの部分が何をやっているのかよく分からないので、どなたか解説をお願いします。 int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; while (n-- > 0) { if (*p1 != *p2) return (*p1 - *p2); p1++; p2++; } return (0); } return (*p1 - *p2); > (1) ---------------------------------------------------------------------- char *strcat(char *s1, const char *s2) { char *p = s1; while (*s1) s1++; /* s1を末尾まで進める */ while (*s1++ = *s2++) ; /* '\0'が見つかるまでs2をコピー */ return (p); } while (*s1++ = *s2++) ; > (2) ---------------------------------------------------------------------- char *strstr(const char *s1, const char *s2) { const char *p1 = s1; const char *p2 = s2; while (*p1 && *p2) { if (*p1 == *p2) { p1++; p2++; } else { p1 -= p2 - s2 - 1; p2 = s2; } } return (*p2 ? NULL : (char *)(p1 - (p2 - s2))); } while (*p1 && *p2) > (3) p1 -= p2 - s2 - 1; > (4) ---------------------------------------------------------------------- char *strcpy(char *s1, const char *s2) { char *p = s1; while (*s1++ = *s2++) ; return (p); } while (*s1++ = *s2++)   > (5) ;          > (5) ----------------------------------------------------------------------

  • str メンバ関数について

    str メンバ関数について 下記のstring Date::to_string() const のstr()メンバ関数が日付クラスDate、 (インタフエース部、実装部)に定義等が記入されていないので、何処に定義されているか教えてください。 ************************************************************* // 日付クラスDate(第2版:実装部) #include <ctime> #include <sstream> #include <iostream> #include "Date.h" using namespace std; //--- 文字列表現を返却 ---// string Date::to_string() const { ostringstream s; s << year << "年" << month << "月" << day << "日"; return s.str(); } ****************************************************************** // 日付クラスDate(第2版:インタフェース部) #include <string> #include <iostream> using namespace std; class Date { int year; // 西暦年 int month; // 月 int day; // 日 public: Date(); // デフォルトコンストラクタ Date(int y, int m = 1, int d = 1); // コンストラクタ int Year() const { return year; } // 年を返却 int Month() const { return month; } // 月を返却 int Day() const { return day; } // 日を返却 string to_string() const; // 文字列表現を返却 }; ostream& operator<<(ostream& s, const Date& x); // 挿入子

  • オペレータ定義について

    すみません、オペレータ定義について教えてください。 ■以下のようなクラスに、[] が定義されていて、 class String { public:       ・       ・ (メンバ関数がいくつかあり)       ・       // num 番目の文字を返す       char operator[](int num) const;       char& operator[](int num); private:       char* string; }; ■関数はこのように書かれていて、 char String::operator[](int num) const {     // 文字列の num 番目の文字を返す 1     return string[num]; } char& String::operator[](int num) {      // 文字列の num 番目の文字を返す 2      return string[num]; } ■これを →[] main() から使うにはどのようにしたらいいのでしょうか?

  • C言語について質問です

    新版 明解C言語 入門編 この本でC言語を勉強しています。 授業とかではなく自主的にやっています。 入力した文字を出力するプログラムを添字演算子なしで作る問題(演習11-1)を解いてみました。 void put_string(const char *s) { while(*s) putchar(*s++); } int main (void) { char s1[128]; printf("type something: "); scanf("%s", s1); put_string(s1); return(0); } これについて二つの疑問があります。 (1)constと指定されているのにインクリメントされていたら値が変わってエラーが出ないのはなぜか (2)main関数でないほうの関数で*を全て外すと 「パラメータ 's' は const signed char 型として定義されているので signed char * は渡せない(関数 main )」といったエラーが出るのですがなぜか

  • C++で>>演算子のオーバーロード

    C++学習者です。 Visual Studio Community 上で、ある教本を使って勉強しています。 現在Stringというクラスを作って、文字列に対して連結や部分文字列の取り出しなどができるようにするための色々な演算子のオーバーロードをする関数を定義していますが、疑問点がありますので、お聞きしたいと思います。 Stringクラスのプライベート変数は、文字列の長さを表すlength と、new 演算子で動的に確保するメモリー領域の始まりのアドレスを表す *sPtr の二つです。 クラス内ではパブリックなメンバー関数としていろいろな演算子がオーバーロードされていて、これらについてはよく理解できるのですが、friend 関数として定義されている入力演算子(>>)について納得がいかない部分があります。 その関数は次のようになっています。 istream &operator>>(istream &input, String &s) { char temp[100]; input >> setw(100) >> temp; s = temp; return input; } わからないのは s = temp; の部分です。 sはStringクラスのオブジェクトで、temp は単なる文字列なのに、なぜ代入できるのでしょうか? 代入演算子=のオーバーロード関数も下に挙げますが、この中でも単なる文字列をStringクラスのオブジェクトに代入できるようにはなってないように見えます。 const String &String::operator=(const String &right) { if (&right != this){ // avoid assignment of itself delete [ ] sPtr; length = right.length; sPtr = new char[ length + 1]; strcpy(sPtr, right.sPtr); } else cout<< "attempted to assign a String to itself \n\n"; return *this; } どなたか答えて頂けると有難いです。

  • C言語での関数の引数の受け渡しについて

    C言語での関数の引数の受け渡しについて教えてもらいたいのです。 char *p=Goo;  というポインタpがmain関数で定義され、このポインタpをある関数 void func(・・・) に渡すことは出来ますか? つまりポインタを実引数として扱うことはできるのかという事ですが・・・ int p=10; とかだったら、 void func(int test) の関数には、main関数で func(p) で仮引数testにわたせると思うんですが・・・ もし出来るようでしたら、関数の渡し方と定義の記述を教えてください。 どうか宜しくお願いします。

  • c言語の問題です。ファイルからデータを読み込み連結リストに記憶しソートするプログラムです。お願いします

    ソート部分がどうしてもできません。 またソートは以下のアルゴリズムで行うものです 与えられたリストをリストA、ソート済みのリストをリストBとする。処理の開始段階では、リストBは空である。 1.リストAの要素の中で、最大値をもつ要素Cを探す。 2.要素CをリストAから削除する。 3.要素CをリストBの先頭に挿入する。 4.リストAが空であれば終了。空でなければ 1. にもどる。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct physical Physical; struct physical { char name[41]; int age; float height; float weight; Physical *next; }; void read_data(char *file,Physical *p,Physical *tail); int comp1(const Physical *, const Physical *); int comp2(const Physical *, const Physical *); int comp3(const Physical *, const Physical *); int comp4(const Physical *, const Physical *); void sort(char *arg,Physical *p,Physical *q); Physical *listsort(Physical *p, int (*compar)(const void *, const void *)); int main(void) { char s[20],t,u[20]; Physical *p,*tail,*q; p=malloc(sizeof(Physical)); q=malloc(sizeof(Physical)); tail=malloc(sizeof(Physical)); while(1) { printf("CMD>"); fflush(stdout); fgets(s,20,stdin); sscanf(s,"%c %s",&t,u); switch(t){ case 'q':exit(0); case 'r':read_data(u,p,tail); break; case 's':sort(u,p,q); break; case 'd': while(q!=NULL) { printf("%s %d %.1f %.1f ",q->name,q->age,q->height,q->weight ); q=q->next;} break; } } free(p); return 0; } void read_data(char *file,Physical *p,Physical *tail){ FILE *fp; char string[100]; Physical header; tail=&header; header.next = NULL; p->next = NULL; tail->next = p; tail = p; if ((fp = fopen(file, "r")) == NULL) { exit(1); } while(fgets(string,sizeof(string),fp)!= NULL) { sscanf(string,"%s %d %f %f",p->name,&p->age,&p->height,&p->weight); Physical *tail2; tail2=malloc(sizeof(Physical)); tail2->next=NULL; p->next=tail2; p=tail2; } fclose(fp); } void sort(char *arg,Physical *p,Physical *q){ if(strcmp(arg,"name") == 0) q=listsort(p,(int(*)(const void*, const void*))comp1); if(strcmp(arg,"age") == 0) q=listsort(p,(int(*)(const void*, const void*))comp2); if(strcmp(arg,"height") == 0) q=listsort(p,(int(*)(const void*, const void*))comp3); if(strcmp(arg,"weight") == 0) q=listsort(p,(int(*)(const void*, const void*))comp4); } Physical *listsort(Physical *p,int (*compar)(const void *, const void *)){ Physical *q, *max,*s,*head; s=malloc(sizeof(Physical)); head=malloc(sizeof(Physical)); head=NULL; while(p->next){max = p, q = p->next; while( q->next ) { if( compar(q->next,max->next) ) max = q; q = q->next;} s=max->next; max->next=max->next->next; if(head==NULL) {head=s;} s->next=s; } return head; } int comp1(const Physical *a, const Physical *b){ return (strncmp(a->name,b->name,sizeof(Physical))); } int comp2(const Physical *a, const Physical *b){ if(a->age > b->age) return 1; else return 0; } int comp3(const Physical *a, const Physical *b){ if(a->height > b->height) return 1; else return 0; } int comp4(const Physical *a, const Physical *b){ if(a->weight > b->weight) return 1; else return 0; }

  • 上からよんでも下から読んでも同じか?否か?

    以下のプログラムは入力された文字をポインタを使ってpalindromeにコピーしたやつなんですが #include <stdio.h> int main ( void ){ char origin[256]; char palindrome[256]; char *p; char *q; int length = 0; printf("文字列を入力→"); scanf("%s",origin); p = origin; q = palindrome; while(*p != '\0'){ *q = *p; p++; q++; length++; } *q = '\0'; printf("length = %d\n", length); printf("入力された文字:%s",palindrome); getchar(); getchar(); return(0); } これをポインタを使って上から読んでも下から読んでも同じ(いわゆるかいぶんってやつ?)なら1を、違ったら0を返すというプログラムを組みたい場合に文字配列,及び文字配列長を引数とする関数check_anagram を使用してどのように表せるのでしょうか? とりあえずヘッダは<stdio.h>のみでできるようにしたいのですが・・・・ lengthを関数内で使ってfor文で処理? そこら辺の組み方がわからないです。

専門家に質問してみよう