トップページ⇒tech
1001コメント323KB

C++相談室 Part3

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
v(^・^)v

C++ Final Draft International Standard
http://www.kuzbass.ru/docs/isocpp/

STLport
http://www.stlport.org/
Boost C++ Libraries
http://www.boost.org/
0153デフォルトの名無しさんNGNG
>>151
ない。オーバーライド「しなければならない」か「しなくてもいい」かの違いだけ。
0154デフォルトの名無しさんNGNG
>>152と>>153で食い違ってるな
0155151NGNG
ああ、なるほど。

くいちがってないでしょ。
>>153はちょっと言葉が足りないけど。
性格には、インスタンス化するならば「しなければならない」
つまり、オーバライドしなければ抽象クラスになる。

だよね?
0156デフォルトの名無しさんNGNG
クラスを複数のファイルに分けてるんですが
こんなエラーでてしまいます

Base.h
class Base{
〜〜
};

Der1.h
class Der1 : public Base{
〜〜
};

Der2,h
class Der2.h : public Base{
〜〜
};

main.cpp
#include "Der1.h"
#inlucde "Der2.h"

Base.h(7) : error C2011: 'Base' : 'class' で示される型としてすでに
定義されています。

どうしたらいいでしょう?
0157デフォルトの名無しさんNGNG
>>156
#ifndef か #if !defined つかいなはれ。
0158デフォルトの名無しさんNGNG
main.cpp
#include "Base.h"
#include "Der1.h"
#inlucde "Der2.h"
でいいだろ。

だがそれ以前に、本当に継承しなきゃいかんのかと、聞きたい。
問いつめたい。
0159デフォルトの名無しさんNGNG
>>158
なんで?
0160156NGNG
>>156
それもよくわからないので
ちょっと調べてみます

>>158
勉強中なので特に意味はないのです。。。
0161デフォルトの名無しさんNGNG
>>160
こんな風に各ヘッダにおまじないしておけば、一度読み込まれたヘッダが
二度読み込まれることがなくなり、再定義errorを防げるんだよ〜。>>157
(INC_BASEとかの名称はお好きなものを)

Base.h
#ifndef INC_BASE
#define INC_BASE

class Base{
〜〜
};

#endif
0162デフォルトの名無しさんNGNG
↑俗称: インクルードガード
0163デフォルトの名無しさんNGNG
>>162
適当な名前でインクルードガードをつけると、あとでハマルことがあるので注意ね。昔 "Types.h" と
"DLib/Types.h" が両方 _H_TYPES_ というインクルードガード使ってたことが(元々別のプロジェクト
から持ってきたファイルだから、仕方ないんだが)。

私はファイル名と GUID からインクルードガードの文字列を作るプログラムを書いて、使ってます。
0164デフォルトの名無しさんNGNG
_で始まる名前は予約語だっつーの。
K&R嫁。
K&R読んで理解スレ。
0165デフォルトの名無しさんNGNG
>>164
C++ スレで K&R 読め、というのは初めて見たが(w
0166デフォルトの名無しさんNGNG
>>164
マジデスカ?
0167163NGNG
>>166
164 が何を憤ってるのか良く分からんが(_H_TYPES_ なんてつけたの俺じゃないぞ) _ で始まる名前は
使わんほうが良いというのは正しい。ANSI C++ の規格書から抜粋ね。

17.4.3.1.2 Global names
1 Certain sets of names and function signatures are always reserved to the implementation:
- Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase
 letter (2.11) is reserved to the implementation for any use.
- Each name that begins with an underscore is reserved to the implementation for use as a name in the
 global namespace.
0168デフォルトの名無しさんNGNG
>>167
__はまるきりだめで
M_aとかも駄目なんですね。
テンプレート仮引数とかも分けたいと思うから
悩み増えます。本当はSGI風のまねたかった。
0169デフォルトの名無しさんNGNG
__で始まる名前と _ + 大文字 で始まる名前がダメ、といっているように読めるが?
0170166NGNG
>>167
うわ、、、ちょっとビツクリ
_fooみたいなグローバルな名前はダメそうだと思っていたんだけど、
_Foo とか hoge__hoge みたいのはあらゆるところでダメ(であってる?)
ていうのは初耳・・・

で、これってマクロにも当てはまるの?
0171デフォルトの名無しさんNGNG
>>170
> で、これってマクロにも当てはまるの?
当てはまるでしょ。

たとえば cygwin だ <errno.h> に関数 __errno() の宣言が書いてあります。もし、ユーザが

#define __errno  1

なんてマクロを定義して <errno.h> を include すると、宣言部分でエラーになりますよね。
それに、標準ヘッダのコードガードとかち合う可能性もありますし。
0172166NGNG
>>171
そういえばそうですね・・・
いままで
#ifndef __MyTools_h
みたいなやつでいっぱいくくってるよ・・・まあ、かち合わなきゃいいや
0173デフォルトの名無しさんNGNG
constは確かにstaticにするべきですね
勉強になりました
3つも方法を教えていただきありがとうございました
0174デフォルトの名無しさんNGNG
>>173
おまえは誰だ!?
0175デフォルトの名無しさんNGNG
>>174
126の亀さんと思われ
0176名無しサソNGNG
 クラスの中でクラスの定義を行っていて、中のクラスから
外のクラスのメンバにアクセスしたいのですが、

class A{
int a

class B{
void b();
}
}

void A::B::b()
{
A::a = 2;
}

でb内でaにアクセスしようとしたら、
「スタティック メンバ関数内の不正なデータ メンバへの参照です」
と言われて、怒られてしまいます(コンパイラはVC6)。
この場合、A::aにアクセスする方法はあるんでしょうか?
0177名無しサソNGNG
 すみません。忘れていたのでageます。
0178デフォルトの名無しさんNGNG
やりたいことが良くわからないが、一応これでコンパイルはできる。

class A
{
public:
static int a;

class B
{
public:
void b();
};
};

int A::a;

void A::B::b()
{
A::a =2;
};
0179補足178NGNG
Bが定義されてる場所は特に関係なく、
たんにstaticメンバ定義方法が間違って板だけ。
0180178NGNG
あ、早とちりしたかも。
staticにしたくないのなら、たとえばこんな方法。

class A
{
public:
int a;

class B
{
public:
void b(A& arg);
};
};

void A::B::b(A& arg)
{
arg.a = 2;
};
0181デフォルトの名無しさんNGNG
>>180
A::A() : B(this) { }
ってやるの?
たしか、この位置でthis使っちゃいけないはずだけど
0182デフォルトの名無しさんNGNG
>>181
んー、どーもやりたいことが良くわかんないけど
クラスBは何のためにネストしてるの?
AはメンバとしてBを持ってないの?
0183181NGNG
いや、俺は176じゃないっす。
ただ、文法的に間違いだと思ったから突っ込んだだけ
0184デフォルトの名無しさんNGNG
>>183
まちがってないよ、コンパイルできたし。
>>180で定義されてる void A::B::b(A& arg)をコンストラクタと
勘違いしてない?
0185デフォルトの名無しさんNGNG
そもそもこの定義だけだと、
たとえばMain関数でAをインスタンス化してもBのインスタンスは
どこにもできない。別途作る必要がある。
だから>>176の意図をもっと聞かないと、どうしたいのか良く分からない。
0186エディタを作ってますNGNG
あの、C++じゃなくてCの方だと思うんですが、教えて下さい。
c=getch()のループでキー入力を取得しているのですが、
altとctrlとescが入ってきません。
こういった特殊なキーを入力するにはどういった関数を使えばいいのでしょうか?
コンソールなので、メッセージ処理以外の方法で教えて下さい。
0187デフォルトの名無しさんNGNG
>>186
こっちでやりましょう。
http://pc.2ch.net/test/read.cgi/tech/1003418249/
0188shigeNGNG
面倒くさいなら、cursesでkeypad()
0189login:PenguinNGNG
>>147
> JISのC++の規格ってないの?

あるよ。http://www.jsa.or.jpで買いな。一度見たければ赤坂へ行け。

>>145
> そのPDFとhttp://www.kuzbass.ru/docs/isocpp/
> の内容は異なるのでしょうか?

違う。そのURLのはfinal draftだから、最後の修正が反映されてない。
ISOの著作権が発生する直前の版。この版はPDF, PS, HTML, TEXTが揃っている。
0190189NGNG
あ、違うっていっても、ほんの少しね。字句の修正レベルがほとんど。
0191名無しサソNGNG
>182
>185

 スマソ。書き忘れです。

class A{
 int a

 class B{
  void b();
 }
 B *b;
}

 と言う感じで、Bのポインタを持たせて、Aのコンストラクタが
呼ばれた時点でnewしようとしています。クラスBは継承された
描画関数で、Aは物体です。で、Aを描画するために、Bで継承
してオーバーロードした関数内に、Aのメンバ変数が欲しいな、と・・・。
AはBと大きく違うし、複数のBみたいなクラスを持っているので、
描画クラスから継承したくはないと思っています。

 初期化したときにクラスAのポインタをコンストラクタでクラスB
に突っ込む事で動作するようにはなりましたが、こんな汚い方法
以外で出来ない物かと。
0192デフォルトの名無しさんNGNG
やっぱり、Class BをAの中でネストト定義する理由がわからない。
外で定義したほうが、変な制約つかなくていいと思うのだが。
0193192NGNG
こんな感じじゃだめなのかな・・・

class Picture
{
public:
int data[256];
};

class Canvas : class Graphics
{
public:
void Draw(Picture& p){/*pをCanvasに描画*/}

};

int main()
{
Canvas canvas1;
Canvas canvas2;
Picture pic;

canvas1.Draw(pic);
canvas2.Draw(pic);
return 0;
}
0194デフォルトの名無しさんNGNG
>>191
 描画対象のオブジェクト
 描画方法

それぞれ独立したクラス階層で管理して、最終的にまとめたい、と。それだとコンポジション使う
場面だと思うなぁ。

class AObject { /* */ };
class DrawImpl1 { /* */ };
class DrawImpl2 { /* */ };
struct ObjectInterface {
  virtual void doSomeThing1() = 0;
  virtual void doSomeThing2() = 0;
  /* */
};

class A
  : public ObjectInterface
{
  AObject aobj_;
  DrawImpl1 draw1_;
  DrawImpl2 draw2_;

  void doSomeThing1() {
    draw1_.doSomeThing(aobj_);
  }
  void doSomeThing2() {
    draw2_.doSomeThing(aobj_);
  }
};
0195192NGNG
誤 class Canvas : class Graphics
正 class Canvas : public Graphics
0196192NGNG
>>194
う、かぶった。
>>194のほうがよりOOを意識してるけど、言いたいことはたぶん同じ。
0197名無しサソNGNG
 みなさん、どうもです。C++は触って結構経つのに、未だに
仕様を使い切れてない物で・・・。

>192
>193
 言われていることを見ると、外のクラスのメンバにアクセスできる
訳じゃないので、ネストは確かに間違いっぽいですね。
要は、そのmainで定義・処理されている部分を隠蔽したい(canvas
をpic内部に持ちたい)、と言う話なんですよ。となると、>194で
書かれている方法に切り替えた方が良さそうですね。
0198 NGNG
delete 0;
って無害だったっけ?
即答で頼む。
0199sageNGNG
無害。
0200 NGNG
>>199 thx;
0201  NGNG
どこかにcursesでダイアログボックスみたいのを出せたり、
メニューをつけたりできるようなクラスないですか?
0202 NGNG
早く教えて!!
昼休みが終わっちゃう!!
0203名無しさんNGNG
>>1 v(^・^)v
なんすか、コレ
0204デフォルトの名無しさんNGNG
きっと、複雑怪奇なマクロが前スレで#defineされてるんだよ。
0205デフォルトの名無しさんNGNG
int i = 0;
cout << i++ << i++ << i++ << endl;
の動作の合理的な説明してください。
0206デフォルトの名無しさんNGNG
>>201
newt
0207デフォルトの名無しさんNGNG
>>205
お?てっきり012って出力されるかと思ったんだけど
210って出力された。なんで?
0208無名λ式NGNG
>>205
(((cout.operator<<(i++)).operator<<(i++)).operator<<(i++)).operator<<(endl);
http://www.gotw.ca/gotw/055.htm

Objectをpost-incrementしたい、かつ、post-increment演算子を一つの定義で済ませたい。
0209デフォルトの名無しさんNGNG
>>208
それで207のようになるのは不思議。
これは不定ってことだよね?
0210デフォルトの名無しさんNGNG
207です。
>>209
コンパイラによって結果が違うの?
ちなみに私はLinuxのGCCでコンパイルして試しました。
0211デフォルトの名無しさんNGNG
>>210
結合順序の問題だから、不定ってことは無いと思われ。
0212デフォルトの名無しさんNGNG
う〜ん、なんだかこんがらがってきた・・・
職業プログラマさん達には常識的な知識なのかな?
私はただいまC++勉強中なんで208を理解するには
時間がかかりそう。
0213デフォルトの名無しさんNGNG
>>209
そういうことですね。
式中の副作用(side effect)が実行される順序は、いくつかの場合を除いてほとんど不定と思ったほうがよい。
VC++だと、副作用が確定するシーケンスポイントはこんなふうに規定されてます。
http://www.microsoft.com/JAPAN/developer/library/vclang/_pluslang_c.2b2b_.sequence_points.htm
gccの場合の規定はどこに書いてあるかわかんなかった。
0214 NGNG
複数行に分けて記述すれば済むだろう。
0215デフォルトの名無しさんNGNG
ガーン。
今度のプロジェクトでSTLの使用禁止令が出てしまった。
用意されてるのはイテレータも無い、出来の悪いlistとmapだけ。
vectorを使いたいと言ったら、代替クラスを作れだと。
STLportでいいじゃん・・・。
愚痴スマソ。
0216デフォルトの名無しさんNGNG
>>215
理由はなんなんだい?
0217デフォルトの名無しさんNGNG
>>221
不定というか、処理系依存というか。
いずれにしろ、そういうコードは書かない方が。
0218デフォルトの名無しさん NGNG
ちょっと問題がわからないので質問です。

bbbbatttooのような文字列をb5a1t3o2のように文字種と連続回数で書き表すことによって
文字列の長さを圧縮する方法を連長圧縮という。
aからyまでの文字を1文字づつ入力として受け付け、zが入力されるまでこれを繰り返す。
連長圧縮を行って結果を出力せよ。

例:入力 a
a
u
 
  出力 a2u1

やり方がぜんぜんわからないので、教えてください。
0219デフォルトの名無しさんNGNG
>>215
STLのvectorのコードそのまま持ってきて「代替クラスです」って言い張るとか。
0220デフォルトの名無しさんNGNG
>>218
まず連長圧縮の内容を理解する
 ↓
(プログラムでやる代わりに)自分の頭でその処理をやるとき、どういう風にやるか考えて、紙に箇条書きする
 ↓
そのままプログラム化
 ↓
(゚д゚)ウマー
0221デフォルトの名無しさんNGNG
う〜ん、文字を使うやり方はなれていないので・・・
charを使うんですよね?
0222215NGNG
理由は「信頼性が無いから」だって。
既存のSTLのvectorを使いたいなら、
・信頼性を証明して
・性能を検証して
・是非使いたい理由を提示しろ
ということらしい。

auto_ptrならともかく、vectorだったら問題ないと思うんだけど・・・。
ちなみに会社はF系列です。ここはこんなんばっか。
驚くことに、stringの代替クラスまでありました。
素直にstring使えよ・・・。
0223デフォルトの名無しさんNGNG
>>222
既存のvectorの代わりに自分で作った代替クラスなら
信頼性があるんだ・・・・・・ふーん。へーぇ。

ぜひ使いたい理由:
「既にあるものを使わず同じ物を新しく作ると、無駄な時間がかかる。
無駄な時間がかかるということは、無駄な金(人件費)がかかる。
我々には無駄に浪費できるほど金が余っているのでしょうか?」

金が余ってるなら、それでいいです。別に異議はありません。
0224デフォルトの名無しさんNGNG
>218
ランレングス圧縮は簡単よ。

この前までちゃんとソースも提供したり、書き上げたりもしたけど、
これじゃ学生クンのためにはならないと気づき、ヒントのみにするヨ

ランレングス圧縮は、連続した文字列を記号と数で表現するものナノヨ。
例えば、aaaabbcだと、a4b2c1となるわけネ。
アルゴリズムは

1:n = 1
  ↓
2:文字を受け取る
  ↓
3:文字列(ファイル)の終端?
YES→goto 9 NO→goto 4

4:次のに取得される予定の文字は同じ文字か?
YES→goto 5 NO→goto 7

5:nをインクリメント
  ↓
6:goto 2

7:"入力された文字"'n'を出力
  ↓
8:goto 1

9:"入力された文字"'n'を出力
  ↓
10:end

ソラで書いたから間違ってるかもネ
0225224NGNG
漏れも工房時代に自作AVGの画像圧縮をしたいが為に
ランレングスヤッターヨ。あの頃はPC98でした・・・
鮪真似たりいろいろやったよ。
今じゃ一端のアウトローなゲームプログラマですわ(;´Д`)

ガンバレ学生タン!
0226名無しさんNGNG
C/C++で、Excelファイルを扱う際に、
列(A,B、C,・・・)を選択するには
どうしたらいいでしょうか?
普通にやるとA列のみに格納されます。
0227デフォルトの名無しさんNGNG
>>222
プラットフォームが書いてないけど、
特殊な環境向けならコンパイラちゃんとしてなくてもおかしくないし。

それでSTL使って問題が起きた時に、
「STLのバグなのでどうしようもありません」とか言われると困る。
0228215NGNG
>>227
>プラットフォームが書いてないけど、

Solaris8のForte6とかいう奴らしいです。
SolarisのC++は初めてだけど、そんなにダメダメなんでしょうか?
0229デフォルトの名無しさんNGNG
>>228
標準じゃなくて、STLPort使用するようにすれば?
こっちは実績もあるから。
0230215NGNG
>>229
そうか、そうですね。
駄目もとでSTLportの使用を主張してみます。
0231デフォルトの名無しさんNGNG
218です。
やっぱりランレングスのプログラムだけはうまくかけません。

大体わかったのですが、一度にすべての文字を出力する方法がわかりません。
たとえば、a3d2f1のようにできないのです。
この問題だけは終わらせないとマズイのでマジでヘルプです〜。
0232デフォルトの名無しさんNGNG
>>231
答えが知りたい?
0233デフォルトの名無しさんNGNG
>>231
224の方針でプログラムが書けたんだね?じゃああとは、
結果を逐一coutに出力せずに、適当なstrstreamに出力するように変更。
最後にその内容を一気にcoutに出す。てなかんじでオーケー。
0234ゲイ2NGNG
WindowsAPIの

CreateFontIndirect(&lf)
LOGFONT lf;

の使い方教えてください。
0235デフォルトの名無しさんNGNG
>>234
MSDN読めばわかる。で、もし続けたいならこっちのスレで。
「Win32AP質問箱」
http://pc.2ch.net/test/read.cgi/tech/991576947/l50
0236デフォルトの名無しさんNGNG
delete [] obj_array
を使って疑問に思ったのですが
何でこれでクラス配列に割り当てたメモリが全て解放されるのでしょうか?

それと、delete base
で、baseが派生型へのポインタの場合(実体は違うクラス)
問題が生じますか?
0237デフォルトの名無しさんNGNG
>>236
割り当てたアドレスの始端 & 割り当てたサイズ
が把握できていれば型は関係ないと思うが。C/C++では配列 = ポインタ
として扱うことができることから類推できないか? 配列といっても
JavaやC#なんかとは違う。
0238デフォルトの名無しさんNGNG
>>236
実装によると思うけど、メモリブロックのサイズを調べて、
その先頭から最後まで順にデストラクタを適用するだけじゃない?
VC++でアセンブリコード吐かせてみたらそうなってた。

baseのデストラクタがvirtualなら問題なし……だと思ったが。
0239デフォルトの名無しさんNGNG
>メモリブロックのサイズを調べて、
まだ、私はメモリがどう扱われているかわかっていないようです
メモリブロックのサイズを調べるのは,コンパイラですよね

>割り当てたアドレスの始端 & 割り当てたサイズ
a[10]
だと、aがベースアドレスで
配列の添え字と型で、アクセスするアドレスを決定するのですよね?

だから、
delete a[10]
ならわかるのですが
delete [] a
というところが,納得いかないのです
例えば
del(A a){
delete [] a;
}
なんてのもありなわけです
0240デフォルトの名無しさんNGNG
>>239
コンパイラは変数の型を知ってます。
0241デフォルトの名無しさんNGNG
>>239
言語仕様です。
0242デフォルトの名無しさんNGNG
>>239
| メモリブロックのサイズを調べるのは,コンパイラですよね

よくある実装ではメモリブロック自身にサイズ情報が含まれており
delete[]が実行時にメモリサイズを調べている。
0243デフォルトの名無しさんNGNG
WindowsXPで他のユーザーがログオンしているかどうかってどうやって調べるの?
0244デフォルトの名無しさんNGNG
>>243
システムコール使う以外ないでしょ
0245デフォルトの名無しさんNGNG
STLスレが死んでいるのでこちらで質問です。

std::listとstd::map を例外安全かつ中立な実装にできないかな?

型引数として渡されるクラスが例外安全・かつ中立であると
仮定しての話でよいです。

すでに、例外安全だったら素マン。出直してくる。
0246デフォルトの名無しさんNGNG
>>244
ありがとう〜。
ネタでなくドキュソを承知で聞きます。システムコールってなあに?
0247デフォルトの名無しさんNGNG
http://www.google.co.jp
へどうぞ
0248デフォルトの名無しさんNGNG
>>245
話についてけない厨房ですんません。
例外安全でない実装ってどのあたりか教えてー。
0249245NGNG
うっ
複数要素の挿入を除いては安全かつ中立であると、書いてあった。

というわけで、出直してきます
0250デフォルトの名無しさんNGNG
ExceptionalC++をオススメしておく。>>248
0251248NGNG
>>250
本屋で探してきます。ありがと。ちゅ。
0252デフォルトの名無しさんNGNG
「例外安全」「中立」ってなに?
用語がわからん
■ このスレッドは過去ログ倉庫に格納されています