dポイントプレゼントキャンペーン実施中!

#include <iostream>
#include <string>

class test : public std::string{
};

int main()
{
test tmp;
tmp = "aaa";
}

tmp = "aaa";ですが
test::operator =(char *)
が定義されていないとでますが何故なんでしょうか?
string(basic_string)でoperator=が定義されていると思うのですが、
演算子の定義は継承されないのでしょうか。

A 回答 (6件)

結論から言ってしまえば、class test に、char * を引数とするコンストラクタがないからです。



「演算子」というくくりでは、普通は継承されます。例えば、

test tmp1;
test tmp2;

に対して、
tmp1 == tmp2 という比較は、文法上有効です。

さて、operator=() は、例外で、ユーザーが明示的に定義しない場合、まず、暗黙の型変換(char * → test)をしようとします。

これは具体的には、test::test(char *) というコンストラクタの呼び出しになります。

が、test::test(char *) が存在しないため、代入もできないというメカニズムのようです。
    • good
    • 0
この回答へのお礼

ご回答有り難うございます。
おっしゃる通りコピーコンストラクタを用意するとコンパイルが通るようになりました。

お礼日時:2006/01/19 17:22

> SGI STLには含まるんですよね?



確かにバージョン3.1ぐらいからSGIのSTLにもbasic_stringが入っていますね。標準C++に導入されたころのSTLにはまだ入ってなかったはずです(というより、標準C++のものをSTLにバックポートした)。ISO/IEC 14882の中にはSTLとかStandard Template Libraryという言葉は出てこないので、単にSTLといえばSGIのものを指すと考える方が妥当なのかもしれません。そうであれば、basic_stringはSTLに含まれるという結論になるかと思います。

とはいえ、実際にSGIのSTLを使っている人は率からいうとそんなにないわけですし、普通は標準C++ライブラリの一部と考えるのが妥当ではないでしょうか。
この辺はちょっと微妙ですね。

> std::vectorやstd::listはSTLですよね??

こちらは間違いなくSTLです。
    • good
    • 0
この回答へのお礼

わざわざお答えくださり有り難うございました。

お礼日時:2006/01/21 00:16

> STLは奥が深い。

。。

いや、basic_stringはSTLではありません。
    • good
    • 0
この回答へのお礼

ご指摘有り難うございます。
SGI STLには含まるんですよね?
http://www.sgi.com/tech/stl/basic_string.html

std::vectorやstd::listはSTLですよね??
質問内容がそれてしまいましたが、もしよければお答え頂けないでしょうか。

お礼日時:2006/01/20 10:48

直接の原因は、testクラスに変換コンストラクタまたは代入演算子が定義されていないところにあります。



あと、#3の方の意見とも関連するのですが...

basic_stringはpublic継承には余り適していません。継承で解決するより、テンプレート引数のtraitsやAllocatorを摩り替える方がよいでしょう。振る舞いを変えるのではなく、インタフェースを追加するのであれば、メンバ関数としてより、フリー関数(非メンバ関数)にした方がよいでしょう。
    • good
    • 0
この回答へのお礼

traits:その存在をはじめて知りました。そんなものが指定できたのですね。
STLは奥が深い。。。

お礼日時:2006/01/19 17:24

直接の回答ではないのですが……



string を継承するというのがちょっと気になりまして。
ご質問の内容が、単純に興味からであれば別ですが、string を継承する必要があるとお感じだとしたら、それは、設計を間違っているのかも知れません。
(そういうケースが多いのです)

string の継承は、例えば、データをすべて小文字として扱う string とか、数字しか受け付けない string とか、10文字以上は受付けない(適切に処理する) string とか、いずれも、……という string を定義するものです。
こういう用途であれば問題ありません。

よくある間違いは、本来、class のメンバーとして string を持つべきものでも、string を継承させようとするものです。
string を継承すべきなのか、string メンバーを持てばいいのか、そのあたりご検討を。

既に、ご検討済みであれば失礼しました。

参考URL:http://www.cmagazine.jp/src/kinjite/cpp/idea.htm …
    • good
    • 0
この回答へのお礼

そういったコーディングを実際しているわけではなく、
あくまで興味の質問でしたがご意見勉強になりました。

お礼日時:2006/01/19 17:24

operator=は特殊で継承されません。


これを回避するためのテクニックは
string& test::operator=(const char* T)
{
/*test独自のコピー処理をここに記述*/
return string::operator=(T);
}
string& test::operator=(const string& T)
{
/*test独自のコピー処理をここに記述*/
return string::operator=(T);
}
string& test::operator=(const char T)
{
/*test独自のコピー処理をここに記述*/
return string::operator=(T);
}
を宣言することです。

operator=が継承されない理由としては
string::operatorでは
追加されたメンバがコピーされないためです。

なお派生クラスには親クラスのオブジェクトが代入可能なので上のコードは有効です。
    • good
    • 0
この回答へのお礼

ご回答有り難うございます。大変参考になりました。

お礼日時:2006/01/19 17:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!