C++のstringクラスの内部の挙動とは?

このQ&Aのポイント
  • C++のstringクラスでは、文字列を直感的に代入することができますが、その内部の挙動について疑問があります。
  • stringクラスでは、=演算子のオーバーロードを使用して、変数宣言と同時に文字列を代入しています。
  • しかし、自作のクラスでは同じような代入ができないため、stringクラスの実装方法が気になります。
回答を見る
  • ベストアンサー

C++でのstringクラスの内部の挙動

最近C++でクラスを理解し始めて疑問に思ったことなんですが。 string A = "abcdef"; という風に直感的にstringに文字列を代入出来ていたので何の疑問も持たず使っていたんですが、これをどのように実現しているか内部の挙動がよくわかりません。 srtcopyはやり方は面倒臭いですがこっちは単純に関数に値を渡しているだけなので理解出来ます。 内部で=演算子のオーバーロードをしているんじゃないかと思って、=演算子をオーバーロドした自分で作ったクラスでテストしてみたんですが Testclass A; A = "abcdef"; は可能ですが、stringの例のように変数宣言と同時に代入する Testclass A = "abcdef" としてみると、Testclass型への変換が出来ませんとなって、string型と同じ事が出来ません。 stringクラスの中でどのようにクラス宣言直後の代入をしているか教えてください

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

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

代入ではなくて初期化です。コンストラクターで初期化できます。

nasumiso2022
質問者

補足

やってみたら出来ました コンストラクターによる初期化は TestClass A(変数); のようにしないと出来ないと思っていました・・・ 回答ありがとうございます。

関連するQ&A

  • 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; } どなたか答えて頂けると有難いです。

  • String型の変数に代入されている2つの文字列を論理演算したいです。

    String型の変数に代入されている2つの文字列を論理演算したいです。 上記の通りなんですけど 例えば String a = "あいうえお"; String b = "aiueo"; このような二つの文字列を論理演算したあと 16進数の文字列としてあらたな変数(String型)に代入したいのですが どのように記述すればよろしいでしょうか? 初心者なものでわかりやすく説明していただけるとありがたいです。

    • ベストアンサー
    • Java
  • クラスを配列で確保する場合のコンストラクタへの引数の渡し方

    例えばコンストラクタのオーバーロードで以下のようなクラスを宣言したとします。 class testClass{ public: testClass(void){ num = 10; } testClass(int num1,int num2){ num = num1 + num2; } int num; }; オブジェクトとして宣言する場合 testClass obj(10,10); と定義とすれば、testClass(int num1,int num2)の方が適用されobj.num = 20となり、問題ありませんが、ここでobjを複数定義したい場合、obj[10]と定義すると上手く引数を渡す事ができません。 以下のような形で宣言するという手もありますが testClass obj[2] = {testClass(2,2),testClass(2,2)}; 例えば定数NUMと定義しておき、 testClass obj[NUM]; という形で宣言したい場合、どのようにすればよいでしょうか? よろしくお願いします。

  • クラスの作成 オブジェクトの生成 メンバ変数へのアクセス

    Person というクラスを宣言し、main メゾットで new 演算子を使ってPerson オブジェクトを作成。さらに、main メゾットでインスタンス変数に値を代入して表示したい。 Person クラスのインスタンス変数には、名前 年齢 給料 を用意する。 変数のデータ型は、順に String , int float です。 Person クラス以外で main メゾットを作成する。 初心者です、本は結構読んだのですが、なかなかわかりませんでした。 おしえてください。

    • ベストアンサー
    • Java
  • Stringクラスのlengthメソッドについて

    こんにちは、Stringクラスのlengthメソッドについて質問させてください。 今まで配列のlengthは、宣言時に長さが決定するからメソッドではなく、finalフィールドで十分。 ArrayListだとかは長さが変わるからメソッドという意識を持っていました。 (カプセル化の概念とも関わりますが) 先日その話しをしていたら、「でも文字列(Stringオブジェクト)の長さも不変だよね。」と言われました。 確かに文字列の長さは不変なのに、長さの取得にはメソッドを使っています。 言語仕様として一貫性を持たせるなら、配列もlengthメソッドにするか、文字列をlengthフィールドにしたほうが綺麗だと思うんです。 Stringクラスのソースコードを見ていたら、文字列の長さは内部的に private int count; と宣言されていました。 そして、lengthメソッドは return count; しているだけでした。 ただ、このcountフィールドに値を代入しているのはコンストラクタ内だけだったので、 public final int length; とすれば、良かったのでは?と思いました。 この考えについて、 それは間違っている、とか歴史的な背景などご存知でしたらご教授ください。 よろしくお願致します。

  • C++ の new演算子について

    C++ の new演算子について質問です。 new演算子を用いてクラスのインスタンスを作ったときに、 クラスのメンバー関数内で使用される自動変数はメモリの何処に割り付けられますか? 以下の回答の内のいずれかと想定しています。 ・ヒープ領域 ・スタック領域 たとえば、以下のように、クラスTestClassが定義されていたとします。 class TestClass { int x; // int型(4byteとする) char y; // char型(1byte) long z; // long型(4byte) void play(short); } void main(void){ TestClass* pt = new a(); play(10); } void TestClass:: play(short n){ char a; long b; static c; for(int a = 0; a < 10; a++ ){ b = n * a; cout << b; } } main関数内で、インスタンスを作成した時点で ・TestClassのデータメンバx,y,z ⇒ ヒープ領域に確保(4+1+4 = 9byte。もしかしたらアライメント     の関係で もう少し大きく領域を確保するかも) ・play関数で使われる変数n,a,bの領域は何処に確保されるのでしょうか? 変数cは静的変数用領域に保存される? new演算子で作ったインスタンスはdelete演算子を使わないと消えないと勉強しました。(OSが消さない限り) つまり、上記ではmain関数を抜けても、変数x,y,z,n,a,bの実体は残ると考えてよいのでしょうか? そう考えると、n,a,bの実体はスタックではなく、ヒープ領域に確保する気がします、、 どうか、ご教授ください。

  • 【C++】ヘッダ内でstringを格納する変数の宣

    【C++】ヘッダ内でstringを格納する変数の宣言ができない 下記クラスのように、string型の変数nameを宣言したいのですができません。 どのようにしてstring型データを格納する変数を宣言すればよいのでしょうか? //--------------- //Neko.h #pragma once #include <string> ref class Neko { private: string name; public: Neko(); }; //--------------- //Neko.cpp #include "StdAfx.h" #include "Neko.h" #include <string> using namespace std; Neko::Neko(){ name = "neko"; }

  • C# このクラス型という限定が何を意味しているのか

    まだC#で実際にコーディングできるレベルではないため ネット上のドキュメントを見ていますと 変数の型宣言にクラス名 関数の戻り値にクラス名 のような書き方を目にします 例 public classA x; public classA x(){}; 一般的には、どのように解釈されてますか? また、同様に宣言にインターフェイス名やデリゲート名を使ったもの public IEnumerator<int> x(){}; public delegateA x;など これら宣言時に具体名を記述する文は iintやchar型などの基本的な型宣言と比べて 内部の挙動と、実際の文がうまくリンクできず 少し頭の中が整理できればと思い質問してみました。 今、僕の頭の中で上記の例は ・参照型という宣言である(専用の修飾子がない) ・そもそも型の宣言ではない ・いわゆる定型文なので、これ以上の応用はなく深く理解する必要もない 一体どれが近いんだろう? という感じで困っています。

  • [言語C#] string型における参照値の受け渡し

    stringは、参照型に分類されると思います。・・・(1) 【string宣言部抜粋】 public sealed class String : IComparable, ICloneable...... また、参照変数の代入では、オブジェクトの参照値が受け渡されるという認識です。・・・(2) 上記(1)、(2)を踏まえると、次のプログラムの実行結果に納得がいきません。 string aiu = "aiu"; string aiue = aiu; Console.WriteLine(aiue); aiu = "abc"; Console.WriteLine(aiu); Console.WriteLine(aiue); 出力結果---------- aiu abc aiu ------------------ (1)、(2)の考えを取り入れた場合、出力結果は aiu abc abc になるものだと思いましたが、なぜこのような結果になるのでしょうか 。自作クラスで似たような処理を行った場合では、一方の変更が同じインスタンスを代入した他方へも影響することは確認済みです。 ただ、stringの場合では・・・違うみたいです。 初歩的なことだと思いますが、宜しくお願い致します。

  • C++ クラスについて

    クラスについて今勉強しています。 そこで質問なんですが クラスの中にクラスというのは実現可能なのでしょうか? クラスAの中にクラスBとクラスCが入っている状態で、 クラスAの中にある関数XでクラスBやCの関数を呼ぶような処理を目指しています。 またクラスAに宣言されている変数をクラスB,Cの中で変更したりできないでしょうか?

専門家に質問してみよう