C++相談室 part62 ..
[2ch|▼Menu]
237:デフォルトの名無しさん
08/06/13 14:19:46
>>236
いや、テンプレートにするかしないかとstaticかどうかは別の問題だから。
つーか、>231の場合でもどうせインライン展開されるから消えてなくなると思うし、
テンプレート関数にしたところでインライン展開されなければ複数できてもおかしくはない。

で、一つにしたい積極的な理由があるの?

238:デフォルトの名無しさん
08/06/13 14:42:06
いろいろ言われそうだけどVCのプリコンパイル済みヘッダーの#include <stdafx.h>
が嫌だからなんです・・。
いろいろなコンパイラで使えればな〜と思っていたらどうしてもこれが邪魔で。
プリコンパイル済みヘッダーの設定変えればいいのでしょうけど、ファイルをコピー、
includeですぐに使えるような書き方はないかな〜と。


239:デフォルトの名無しさん
08/06/13 14:50:41
あ、見当違いなこと書いてたかも。
上記理由でどうせ同じ関数なんだからひとつにしてファイルサイズ減らせないかなと
思っていた次第です。

240:デフォルトの名無しさん
08/06/13 14:52:05
>>239
理由がそれだけなら、最適化するとどうせインライン展開されて消えてなくなるから気にするな。

241:デフォルトの名無しさん
08/06/13 15:27:25
というか、あちこちに同じ中身が生成されるわけだから
ファイルサイズは逆に増えるよね。

242:デフォルトの名無しさん
08/06/13 15:33:47
う〜ん、いろいろありがとう。
とりあえず最適化に任せてみます。

243:デフォルトの名無しさん
08/06/13 16:11:17
===foo.h===
#include "bar.h"
class foo
{
(略)// barは出てこない
};

===foo.cxx===
#include "foo.h"
(略)// barが出てくる

とやるのと、
#include "bar.h"
をfoo.cxxの中に持ってくるのは、
どちらにどういうメリットデメリットがあるのでしょうか。
また、一般的にはどちらの書き方が推奨されますか。

244:デフォルトの名無しさん
08/06/13 16:13:13
CLIって便利だよな
特に他言語で作ったクラスライブラリがそのまま使えるお得感は感動ものだ

245:デフォルトの名無しさん
08/06/13 16:17:15
>>243
ヒント:依存関係、カプセル化

246:デフォルトの名無しさん
08/06/13 17:46:14
>>243
後者。素直に使う所に書く、で必要十分。
前者にメリットは無い。fooを使うやつのコンパイルがbar.hの分遅くなるだけ。

247:デフォルトの名無しさん
08/06/13 18:14:43
次のプログラムをエラー無くコンパイルしたいのですが、方法を教えてください。
//データの構造体-----------
struct dataA
{
int m_dataA;
CLSA * m_next //クラスのポインター
};
//使用するクラス------------
class CLSA
{
dataA m_dat[100];   //データの配列
};
dataAの中にクラスのポインターを持つ。この状態ではCLSAが無いと言われます。
順番を変えるとクラスの中でdataA構造体が無いと言われます。
対処方法が無いでしょうか?


248:デフォルトの名無しさん
08/06/13 18:16:41
セミコロン抜けてた
CLSA * m_next; //クラスのポインター

249:デフォルトの名無しさん
08/06/13 18:32:36
>>247
struct dataAの上に 「class CLSA;」を書く。

あと、どうでもいいけど何かよく分からないデータ構造だな。
dataA{ CLSA* m_parent; } とか
dataA{ dataA* m_next; } とか
CLSA{ CLSA* m_next; } なら分かるけど。

250:デフォルトの名無しさん
08/06/13 20:00:26
出来ましたありがとうございます。基本的な内容ですねorz
データ構造は
root クラスインスタンス
|
|-ノード1クラスインスタンス
| : |-ノード1クラスインスタンス
| : |-ノード1クラスインスタンス
| :
|-ノード1クラスインスタンス

のような多段構造のようなもので、ノード分岐の意味をdataAの内部で示しています。
意味自体が単独で作られたり渡されたりするので、1つの構造体にしています。

251:デフォルトの名無しさん
08/06/13 20:08:54
>>244
そのままシームレスに使えればだがな。

だが現実は・・・・ ハァー

252:デフォルトの名無しさん
08/06/13 22:04:32
>>222
3.9.1 p1 は「バイト中のすべてのビットが値に反映される」とはいっても、ビット列と値が
1 対 1 でないこともあるんじゃないかな。
例えば char が符号付きで符号ビットと絶対値で表現する場合、値 0 を表現するビット列が
2 パターンある。その処理系で char* を通して値 0 を読み、その値を char* を通して書く
とビット列が変わる可能性があるんじゃないかな?

253:デフォルトの名無しさん
08/06/14 00:03:39
char型のコピーはbit列をそのままコピーすると言っているのでは

254:デフォルトの名無しさん
08/06/14 04:05:09
>>252
現行の規格で多少無理やり解釈すれば、 -0 と +0 は == で比較すれば
同じになるとしても、区別可能な(異なる value representation を持つ)二つの値
ということでコピーでビット列が変わる可能性は無い、とは言えそう。

ちょっと苦しいんで調べてみたところ、 C との互換性と合わせて見直しが
提案されているみたい。
URLリンク(www.open-std.org)
この中で C99 の規格を基本的にはそのままパクりながら、 C99 では
保証が無いものの、 C++ で半ば慣習的に行われてきた char による
object representation のコピーを保証するため、以下のような記述の追加が
見られる。

The types unsigned char and char may be used for “bitwise” copy.
[Note: this means that if signed char has a negative zero which is
either a trapping value, or will be forced to positive zero on assignment,
plain char must be unsigned. ?end note]

てきとう訳:
型 unsigned char と char は「ビット的」コピーに使ってもよい。
[注: これは、もし signed char が負のゼロをトラップ値として持つか
代入において正のゼロに強制されるのであれば、ただの char は
unsigned でなければならない、ということを意味する。 -注ここまで]

提案とは別に、議論の中では C++ では2の補数を強制してしまうような話も
出ていたらしい。実際のところはそれでもいいのかもしれない。

255:デフォルトの名無しさん
08/06/14 13:48:22
以下のような二種類の構造体のフィールドなのですが、
どちらがより適切なのでしょうか?

struct A
{
int length; // textの長さ
unsigned char text[0]; // 利用者側で好きに領域を確保して先頭を格納。
};

struct B
{
int length;
unsigned char text[1];
};

違いはtext[1]とtext[0]だけなのですが、
text[1]としてしまうと、

unsigned char text[] = "aiueo";
A* a = (A*)malloc(sizeof(A) + strlen(text));

としたときに(処理系依存ですが)
intで4バイト、unsigned charがパディングされて4バイト
さらに文字列の長さで5バイト確保されます。
これだとunsigned charがパディングされた4バイトは無駄な領域の気がします。

text[1]とするメリットはあるのでしょうか?


256:デフォルトの名無しさん
08/06/14 14:12:25
>>255
宣言より大きい配列のアクセスはお勧めできないと思う。
環境依存なしでそういう構造を作りたいなら
struct A
{
int length; // textの長さ
};
A* a = (A*)malloc(sizeof(A) + strlen(text));
で確保して
char* buff=(char*)(a+1);
で文字列にアクセス


文字列の構造体を作りたいなら以下の方がお勧めかな
struct A
{
int length; // textの長さ
unsigned char* text;
};

257:デフォルトの名無しさん
08/06/14 14:24:31
>>255
unsigned char text[0]; はC89では認められていない。
C99から導入されたflexible array memberを使うなら、
unsigned char text[];

258:デフォルトの名無しさん
08/06/14 14:58:10
>>254
なるほど。
今回初めてC++の仕様書に目を通してみたけど未定義や処理系定義の部分が多くて
正確に解釈するのははなかなか難しいですね。
現状の処理系に合わせて処理系定義の部分を削っていけばかなりシンプルになると
思いますけど。

259:デフォルトの名無しさん
08/06/14 15:18:36
>>258
処理系を前提とした入門書を読もう。 処理系未定義はその後で。

260:255
08/06/14 19:20:57
>>256さんどうもありがとうございます。

struct A{
int a;
unsigned char c[0];
};

gcc -c -pedantic test.c
としたら警告が出ました。

警告: ISO C forbids zero-size array 'b'

gccの独自拡張で可能になっているけれどC89自体では禁止されている
ということですね。

261:デフォルトの名無しさん
08/06/14 20:30:10
おい、お前ら、googleでソースコードの検索ができることを知ってましたか?
URLリンク(www.google.co.jp)

262:デフォルトの名無しさん
08/06/14 20:31:46
お前が今まで知らなかったことに驚愕。

263:デフォルトの名無しさん
08/06/14 20:32:49
どういうときにつかうん

264:デフォルトの名無しさん
08/06/14 20:34:41
codeをsearchする時

265:デフォルトの名無しさん
08/06/14 20:54:24
>>261-264自演乙

266:デフォルトの名無しさん
08/06/14 20:56:31
>>265
自演じゃねーよ、タコが

267:デフォルトの名無しさん
08/06/14 20:58:47
>>266
イカですけど何か?

268:デフォルトの名無しさん
08/06/14 20:59:26
>>267
創価、すまんかった

269:デフォルトの名無しさん
08/06/14 23:11:26
# include<iostream>

using namespace std;
void func(int a = 0,long int b = 1000, double c = 2.9751)
{
cout<<"This is func[i].\n";
cout<<"a="<<a<<", b="<<b<<", c="<<c<<"\n\n";
}

void func(int a,double b =3.4152)
{
cout<<"This is func[ii].\n";
cout<<"a="<<a<<", b="<<b<<"\n\n";
}

void func(long int a)
{
cout<<"This is func[iii].\n";
cout<<"a="<<a<<"\n\n";
}


int main(void)
{
func(0,1000,2.9751);
func(0,3.14152);
func(0);
return 0;
}
オーバーロード関数が呼び出せませんと言うエラーが出るのですが、
何処が間違えているかわかりませんか?
未熟な私に教えていただけたらありがたいです。

270:デフォルトの名無しさん
08/06/14 23:16:36
そんな
かわいそうな
つかいかたを
するな

271:デフォルトの名無しさん
08/06/14 23:22:17
>>269
どれを呼んでいいのかワカンネ。とコンパイラ様は仰っておられる


272:デフォルトの名無しさん
08/06/14 23:23:24
>>269
とりあえず、2個目と3個目のfuncを関数ごと
コメントアウトして実行してみ。

273:デフォルトの名無しさん
08/06/15 02:27:52
もう引数全部意図する型にキャストしちゃえよ

274:デフォルトの名無しさん
08/06/15 02:40:25
既定引数と多重定義は「まぜるな危険」だろ。
危険といっても、だいたいコンパイルエラーか警告だけど。

必要なら既定引数を使わないで多重定義をがんばることもやる。
といってもこういうのはありにしているが。
void f(int x);
void f(double x);
void f(int x, int y, int z = 0);
//実引数1個なら多重定義の解決の候補に既定引数は関係しない。
//実引数2個ならデフォルト引数を使うがfの候補は1つに決まっているので良し。

275:デフォルトの名無しさん
08/06/15 03:02:24
fcloseの定義はどこにあるのでしょうか?
glibc-2.7のソースの中には無いようなのですが…

276:デフォルトの名無しさん
08/06/15 03:07:07
libio/stdio.h

277:275
08/06/15 03:16:44
>>276
ありがとうございます!
あった!なるほど#defineされてたわけですね。
#define fclose(fp) _IO_new_fclose(fp)

で、_IO_new_fcloseをたどっていくと
最終的に__closeという関数が呼ばれているようなのですが、
今度こそ定義がglibcにはありませんでした。
ここから先はどうやって追えばよいのやら…

278:デフォルトの名無しさん
08/06/15 03:17:10
>>275
マクロになってるとかじゃないの?

279:275
08/06/15 03:22:33
すみません__closeありました。
sysdeps/march/hurd/close.c
にありました。

実は、fcloseするときにバッファをディスクに同期する
部分がどうなってるのかを追いたかったのですが、
__closeから先はどうやら単にクローズしているだけのようです。
追いなおします。

280:デフォルトの名無しさん
08/06/15 03:25:42
>>277
それはシステムコールじゃないかね。
そうだと、カーネルのソースを見る必要がある。


281:277
08/06/15 13:41:18
>>280
ありがとうございます。
Linuxのソースを見てみました。

linux/include/asm-i386/unistd.h
の中に

#define __NR_close 6

というのがあって、

linux/arch/i386/kernel/syscall_tables.S
の中のテーブルの6番の位置は

sys_close

となっていたので、sys_closeで探すと

linux/fs/open.c
の中にあって、その中で呼んでいる
filp_close
の中でflushとかやっていました。

ただ、__closeから__NR_closeのつながりがわかりませんでした。
これをどこかで#defineされているものなのでしょうか。

282:デフォルトの名無しさん
08/06/15 13:58:38
C++のスレで話すような話題か、っつーのは置いといて...
今時のOSだと、ユーザアプリがファイルをcloseした
からといって、いちいちディスクに同期は取らんと思うけど。

libcのfclose()は、fflush()を呼ぶなりして、少なくとも
ユーザアプリ(というかlibc)が握ってるデータがkernel側に渡るようにはする。
が、kernel側がダーティページをどう処理するかは、バッファキャッシュ管理の
問題になるんでは。

ぶっちゃけsyncとかがあるのはそのためでしょ。

283:デフォルトの名無しさん
08/06/15 22:44:48
class A { A(); ~A(); A(const A&); void operator=(const A&); friend class X; };
class X { class Impl; Impl* impl_; };

ユーザから見て A オブジェクトの生成と消去を X からしかできないようにしたいけど
impl_ の中で A を何らかのコンテナで管理するとき、そのコンテナは A と friend で
はないので A のコンストラクタとデストラクタを呼び出せません。A の中に実装のため
のクラスを friend として並べたくないし、実装の変更のたびに変更したくありません。

何か簡単に解決する方法はあるでしょうか?


284:デフォルトの名無しさん
08/06/15 23:10:00
>>283
class A を class X か class X::Impl の private メンバにする。

285:デフォルトの名無しさん
08/06/16 00:39:28
>>284
もちろんユーザは A の public メンバにアクセスできることが前提です。

286:デフォルトの名無しさん
08/06/16 00:57:47
>>285
A を抽象インターフェースにして実体を >284

287:デフォルトの名無しさん
08/06/16 01:12:34
template hackerさん。ヘルプミー。

template < class _T >
class C
 {
  public:
   template < class _Ta >
   void X();
 };

template < class _T >
void F()
{
C< int > obj1;
obj1.X<int>();

C< _T > obj2;
obj2.X<_T>();
}

288:デフォルトの名無しさん
08/06/16 01:13:57
めっちゃ途中で書き込んだ。さーせん。
その上のコードの、obj2.X<_T>();がコンパイルエラーで通りません。
何ででしょうか
代替案とかあるでしょうか

289:デフォルトの名無しさん
08/06/16 01:21:27
環境とエラーメッセージくらい書こうぜ

290:デフォルトの名無しさん
08/06/16 01:29:17
ったりめーだろ
class _Tの実体がない

291:デフォルトの名無しさん
08/06/16 01:29:37
じゃなかったclass _Tの定義がない

292:デフォルトの名無しさん
08/06/16 01:33:42
>>286
ああ、その手があったね。

しかも A の唯一の派生クラスを A の friend にしておけば抽象である必要もないし
X の中に入れる必要もないね。

ありがとう。

293:デフォルトの名無しさん
08/06/16 01:34:00
>>290
_Tはテンプレート引数だろ。

294:デフォルトの名無しさん
08/06/16 01:57:05
>>288
obj2.template X<_T>();
その名がテンプレートであることを示せ

>>289
この場合はいらんかも


295:デフォルトの名無しさん
08/06/16 02:02:54
>>294
>>287-288

296:デフォルトの名無しさん
08/06/16 02:21:21
>>287 予約識別子死ね。

297:デフォルトの名無しさん
08/06/16 02:25:06
>>292
> しかも A の唯一の派生クラスを A の friend にしておけば抽象である必要もないし
> X の中に入れる必要もないね。

何か変だな。一般的には、抽象でいいものに実装を混ぜる必要もないし、
スコープを無駄に広める必要もない、となりそうなもんなんだが。

まぁ望むものは得られたみたいなんで、書き込みに出てない部分の都合があっての
話ならどうでもいいけど。

298:デフォルトの名無しさん
08/06/16 07:38:23
これでいいんだよね?

class A {
public:
 virtual ~A() { }
 virtual void Foo() = 0;
};

class X {
public:
 X();
 A* NewA();
private:
 class Impl* impl_;
};

class X::Impl {
public:
 A* NewA() {
  return new AImpl;
 }

private:
 class AImpl : public A {
 public:
  virtual void Foo();
 };
};

X::X() : impl_(new Impl) { }
A* X::NewA() { return impl_->NewA(); }

299:デフォルトの名無しさん
08/06/16 12:39:10
>>297
抽象にしたくないのは単に性能のため。
Aは単純なクラスを想定しているのでそれほど実装を隠す必要はないから。
もしAの実装を隠したい場合はImpl方式にするかもしれない。
抽象クラスより優れている根拠は特にないが。

確かにAの派生はXに入れたほうが名前空間の汚染を軽減できるね。

>>298
デストラクタは private にしてユーザが削除できないようにしたい。
さらに特定のクラスにしか派生できないようにしほうが何となく安心。

300:デフォルトの名無しさん
08/06/16 12:47:35
obj2.template X<_T>();

いや本当は知らないんですけどね

301:デフォルトの名無しさん
08/06/16 23:02:51
>>294
>>300
thx。たすかりますた。thx。
>>287
解った。死ぬから_Tを使わせてくれ。

302:デフォルトの名無しさん
08/06/16 23:03:51
> _T
処理系の予約語じゃねえか・・・

303:デフォルトの名無しさん
08/06/17 21:38:29
ワラタ

304:デフォルトの名無しさん
08/06/17 23:47:32
class x について ++x と x++ を定義する場合
operator++ はどうなるのかしらぁぁぁぁぁぁぁぁ

305:デフォルトの名無しさん
08/06/17 23:53:14
++x → operator++()
x++ → operator++(int)

後者の引数はオーバーロードのためのダミー引数で、
それ以外の何かに使う物ではない。

306:デフォルトの名無しさん
08/06/17 23:55:50
X & X::operator ++ (void) ;
X X::operator ++ (int) ;

307:304
08/06/17 23:59:07
ありがとうございました。orz

308:デフォルトの名無しさん
08/06/18 07:40:42
関係無い話だけど、
テンプレート引数型で後置インクリメント使う馬鹿は氏ねと言いたい。

309:デフォルトの名無しさん
08/06/18 07:56:32
いやむしろ型特性を利用して組み込み型のときだけ後置インクリメントにするという手も

310:デフォルトの名無しさん
08/06/18 13:14:00
VC++ の2005を使用し、C++/CLIでアプリを作成しています。

ListViewに複数項目が登録されている場合、最下段での下キー押下で最上段へ、
また、最上段での上キー押下で最下段にフォーカスを移したいと思っています。

これをやるだけならキーイベントを拾って
「最下段で下キーが押された場合、フォーカス位置を0にする」
というようにすればいいのかと思ったのですが、ListViewのデフォルト機能(?)で
上下キー押下はフォーカス位置を1つずらすようになっています。

つまり、

1
2
3←フォーカス

この状態で下キーを押すと、フォーカス位置が0に戻る処理が実行された後、
フォーカス位置が1つ下にずれてしまうので

1
2←フォーカス
3

となってしまいました。

ListViewが持っているデフォルトのキーイベントを破棄できればいいのかと思ったのですが、
その捨て方も分かりませんでした・・・。

上記要件を満たす方法などがありますでしょうか?

311:デフォルトの名無しさん
08/06/18 13:39:20
スレ違い
.NETスレ行け

312:デフォルトの名無しさん
08/06/18 13:39:59
>>310
C++/CLIはC++を元にした別の独立した言語です。
なので基本的にはC++/CLIスレで質問して下さい。

しかし、言語自体でなく、
ListView(.NETコンポーネント)のことなので、
.NET総合スレか、人の多い(+構文が近い)C#スレをお勧めします。

System.Windows.Forms.ListView などは
C++/CLI, C#, VB.NETで同一のものです。

313:デフォルトの名無しさん
08/06/18 13:52:12
次スレのテンプレには、
C++/CLI関連の誘導を加えた方がよさそうだな

314:デフォルトの名無しさん
08/06/18 14:25:33
>>311、312
失礼しました
他スレにて再質問します
ありがとうございました

315:デフォルトの名無しさん
08/06/19 14:53:55
以下のプログラムで、ddd() の中のようなキャストを行ってから bbb() の中で B::f() を正しく
呼び出せるでしょうか?

struct B { void f(); };
struct D : B {};
void bbb( B* b[], int size ) { for ( int i = 0; i < size; ++i ) b[i]->f(); }
void ddd( D* d[], int size ) { bbb( static_cast<B**>( static_cast<void*>( d ) ), size ); }

316:デフォルトの名無しさん
08/06/19 15:46:32
ちょっと聞いてください。
enumハックを使ってクラスの中でSIZE_MAXという名前の定数を定義したんですよ。
そしたら、「error C2143: 構文エラー : '}' が '定数' の前にありません。」などのエラーが何個か出ました。
いろいろコメントアウトして原因を探ったら、vectorやstringなどをインクルードするとエラーが出る事がわかったんです。
で、インクルードファイルが壊れてると思い、再インストールしたんですが直らず、
結局、limits.hでSIZE_MAXという名前のマクロが定義されていたのが原因でした。
エラーメッセージに名前は出ないし、ネームスペースも無視される。
マクロって最低じゃないですか?

317:デフォルトの名無しさん
08/06/19 16:00:25
マクロのない言語に乗り換えるといいと思うよ

318:デフォルトの名無しさん
08/06/19 20:39:42
>>316
だからマクロは大文字を使うんだよ。

319:デフォルトの名無しさん
08/06/19 21:15:33
やってみて結果を述べるのが自立した大人の行動と思う。

320:デフォルトの名無しさん
08/06/19 21:15:56
319はto315

321:デフォルトの名無しさん
08/06/19 21:21:24
だから、大文字の識別名はマクロ名以外には使わないという
お約束があるんだよ。

322:デフォルトの名無しさん
08/06/19 21:46:10
>>319
すみません。特定の環境ということではなく一般的にできるかどうかです。
VC8で試したら動きます。

323:デフォルトの名無しさん
08/06/19 22:37:03
やってみた結果から刷り込まれた処理系依存な「知識」が豊富な「大人」は痛いよな

324:デフォルトの名無しさん
08/06/19 22:44:01
>>318,321
列挙型や定数に大文字使ってるのよく見かけるけどそんなお約束あるの?

325:デフォルトの名無しさん
08/06/19 22:51:45
>>324
定数もマクロだったりするし、列挙型はスコープ無いから定数の代わりに使ったりするから


326:デフォルトの名無しさん
08/06/19 23:29:25
std::wstring以外で、汎用的な文字列クラスって言うと何になるんでしょうか。
今までずっとATL::CStringWでやっていたのですが、std::wstringはいまいち不便で。
boostあたりになっちゃうんでしょうかね。

327:デフォルトの名無しさん
08/06/19 23:49:29
>>325
>定数もマクロだったりするし、
定数をマクロで書くのはよくないんじゃない?
Effective C++ 1項に書いてあるように、これこそお約束なのでは。

>列挙型はスコープ無いから定数の代わりに使ったりするから
>>316の例だって列挙型を定数がわりに使ってハマってるように見えるんだが、何か違う?


328:デフォルトの名無しさん
08/06/20 00:13:55
怪しかったらundef
CreateWindowとか

329:デフォルトの名無しさん
08/06/20 00:35:20
質問です。
あるクラスのインナークラスを他のファイルで前方宣言したいと思っているのですが
どのように宣言すればよいのでしょうか…。

以下例です。
名前空間SpaceAに定義されたクラスClassAがあったとして
ClassA内部にはInnerClassAが定義されているとします。

namespace SpaceA {
class ClassA {
public:
class InnerClassA{}
}
}

このInnerClassAを他のファイルClassB.hで前方宣言して使うことはできるのでしょうか…。

// 前方宣言
namespace SpaceA {
class ClassA;
//struct ClassA::InnerClassA; // ClassAは名前空間じゃないからエラー…どう書けばいいのか
}
using SpaceA::ClassA;

namespace SpaceB {
class ClassB {
public:
ClassB( InnerClassA* p ); // イメージ的にはこんな感じで使いたい
}
}

よろしくお願いします。

330:デフォルトの名無しさん
08/06/20 01:44:36
>>315
D* を B* としてアクセスするのは、規格の 3.10 p15 にあるエイリアスの制約に
違反するので、未定義動作。

ddd() の引数に B* の配列を似たようなキャストしてねじ込んだ場合は、上記の
制約を満たすことになるのでセーフ。

331:デフォルトの名無しさん
08/06/20 01:48:50
>>329
無理。外側の ClassA の定義が必要。 ClassA の中で class InnerClassA; としてあれば
InnerClassA の定義は必要ない。

332:デフォルトの名無しさん
08/06/20 08:20:45
>>315
>D* を B* としてアクセスするのは、規格の 3.10 p15 にあるエイリアスの制約に
>違反するので、未定義動作。

普通のアップキャストだからOKじゃないの?

333:332
08/06/20 08:34:45
332は>>315じゃなくて>>330だった。

なおModern C++ Designでは、
仮想継承でなければstatic_castによる
アップキャストは問題ないとなってた。
規格でどうなってるかは知らない。

334:332
08/06/20 09:16:06
>>330

もしかして static_cast<B**> がダメってことですか?

335:330
08/06/20 09:30:49
>>332
ごめん。まぎらわしいね。

「D* に B*& でアクセスするのは、〜」ってことで、少しは伝わりやすいかな、と。

336:デフォルトの名無しさん
08/06/20 13:36:27
C++ の仕様では sizeof(B*) != sizeof(D*) の処理系もありえるのかな。

337:デフォルトの名無しさん
08/06/20 15:16:43
クラスが違うとポインタサイズも違うのか・・・?なんという

338:デフォルトの名無しさん
08/06/20 16:08:14
class XをSTL準拠にするため自作イテレータを作ろうと
operator++( X* x )みたくしたら
「クラス型パラメータがひとつもありません」と怒られました。
ハーバートシルト先生のSTL標準講座を読んでも解決法が書いてありません。
っていうか自作STLの書き方なんて載ってないし。
もうだめです。さようなら。

339:デフォルトの名無しさん
08/06/20 16:56:07
はい、さようなら。

340:デフォルトの名無しさん
08/06/20 17:37:07
using namespace std;という呪文が書いてある他人の作ったヘッダ(hoge.hh)をインクルードするのが気持ち悪かったので、

>hogehoge.hh
namespace hogehoge{
#include "hoge.hh"
};

>hogehoge.cc
#include "hogehoge.hh"
……

ってやったらhoge.hhの中でhogehoge::stdをさがしにいきやがったのが納得いかないんですが、
using namespace std;っていうのはstdをグローバルスコープにする命令じゃないんですか?

341:デフォルトの名無しさん
08/06/20 17:52:33
違うよ。
現在の名前空間から見てstd::以下にあるシンボルを現在のスコープにロードする命令だよ。

ちなみに、名前空間のなかから普通の"std"を読み込みたいなら
using namespace ::std;
とする必要がある。

342:デフォルトの名無しさん
08/06/20 18:11:09
>>338
ポインタで横着しようとしないで、イテレータ用のクラスを作る。

343:デフォルトの名無しさん
08/06/20 18:16:56
>>340
hogehoge::stdを探しにいったってことは、
hoge.hh内に namespace std {...} があるのか・・・。

using namespace std;で飽き足らず、
std空間にユーザー定義を追加するとは、不届きなヘッダだなw

とりあえず、

>hogehoge.hh
namespace hogehoge {
namespace std { using namespace ::std; } // これを追加
#include "hoge.hh"
};

しておけばおk。

344:343
08/06/20 18:54:47
あ、hoge.hhにstd系のincludeがあったら駄目か・・・。

345:デフォルトの名無しさん
08/06/20 19:01:52
>>341
うむむ、namespaceは奥深いですね。

>>343
namespace stdは見つかりませんでした。。。
あと、その行を追加してもhogehoge::stdを探しに行ってるように見えます。。。

一番簡単なのはヘッダのusing namespace std;の行を削除することなんだろうけど、
ファイルの上の方のコメントみたらcopyrightとか書いてあるし……

諦めて裸のままインクルードして使うことにします。
ありがとうございました。

346:デフォルトの名無しさん
08/06/21 13:11:25
>>344-345
hoge.hhの中にincludeがあるなら、
それを先にincludeしとけば良いんじゃね?
インクルードガードで無視されるから。
例えば #include <vector> があるなら↓のように。

#include <vector>
namespace hogehoge {
  namespace std { using namespace ::std; }
  #include "hoge.hh"
};

347:デフォルトの名無しさん
08/06/22 23:55:19
定数を指定するとき、C言語では#defineを使いましたが、
C++ではconstな変数を使え、とモノの本に書いてありました

ところで、定数がint型で何個も欲しいのですが、
列挙型の列挙子で代用するのはアリでしょうか?

348:デフォルトの名無しさん
08/06/23 00:09:47
>>347
どれくらいの個数かにもよるかもしれないけど、
列挙子で代用(?)している入門書は結構ある。

349:デフォルトの名無しさん
08/06/23 00:28:08
#define 使うなってのは、型だとか副作用だとかエラーメッセージだとかだから
enum なら問題ないと思うよ

350:デフォルトの名無しさん
08/06/23 00:30:07
配列の添え字に使いたかったんです
単なる数字より、文字のほうが読みやすいですし
ありがとうございました

351:デフォルトの名無しさん
08/06/23 00:34:33
>>347
なんで数が増えたら enum で代用するなんてことになるの?
意味が違うだろ。

352:デフォルトの名無しさん
08/06/23 00:37:28
連番なら enum だね。

353:デフォルトの名無しさん
08/06/23 00:46:05
>>351
いや、0から始まる連番なもんで

354:デフォルトの名無しさん
08/06/23 00:50:15
>>353
それなら代用じゃなくて enum が正解。逆に int const で用意するほうがありえない。

355:デフォルトの名無しさん
08/06/23 03:11:09
すみません.
ここでする質問ではないかも知れませんが.
C++でMPEG2を取り扱うプログラムを作らなくてはならなくなりました.
MPEG2を扱うにはどのようなlibraryを使わなければならないでしょうか?
またそのマニュアルが詳しく掲載しているサイトを教えてくれません?
Directshowは抜きでお願いします.

356:デフォルトの名無しさん
08/06/23 03:25:18
ffmpegでヤフれ

ただしMPEG2特許の利用ライセンスは自分でとってね!

357:デフォルトの名無しさん
08/06/23 16:44:37
VC++環境です。STLのlistについて質問です。
あるlist(Aとする)の情報をまるまる別のlist(Bとする)にassign()で写したのち、
Aのある位置を指しているイテレータをそのままBで使いたい
(Aで指していた位置にある情報を指させたい)
のですが、方法を探しても見つかりません。
アルゴリズムのfind()以外で何か方法はありますか?

358:デフォルトの名無しさん
08/06/23 17:13:09
>>357
std::distance(), std::advance()

ただ、listだとランダムアクセス出来ないから
一応それぞれO(n)で、セットでO(2n)になる。
まぁとんでもない要素数でない限り一瞬だろうけど。

359:デフォルトの名無しさん
08/06/23 17:18:01
listはアクセスするだけでもメモリの中を不規則な順序で飛び飛びするので、平均の次の要素へのアクセス速度は
要素が連続しているvectorよりも遅い。

360:デフォルトの名無しさん
08/06/23 17:24:45
>>357->>359
頭からの距離で考える発想は思いつきませんでした。
要素も少なく、実際に動かしてみても一瞬で処理できました。
ありがとうございました。

361:デフォルトの名無しさん
08/06/23 22:12:24
解決したようだが、
begin()〜itとit〜end()の2回に分けてコピーするのもいいな。

362:355
08/06/24 02:37:33
ffmpegをヤフりました.
MS-DOSで動くオープンソースの動画変換アプリなんですね.
ソースを見て参照方法を探れということですね?
これも方法の一つとしますが時間がかかるので,なにか他の方法はないでしょうか?

それと商用配布は考えていないのでライセンス申請の必要はありません.

363:デフォルトの名無しさん
08/06/24 03:12:10
いいえ、商用に限らず許可なく使うことは許されません。

364:デフォルトの名無しさん
08/06/24 07:35:29
特許権は、それを使ったものを製造、保管、流通することを制限することができるよ。
商用かどうかは関係ないよ。
詳しくは法務に聞こうね。

365:デフォルトの名無しさん
08/06/24 10:47:36
>>362
> MS-DOSで動くオープンソースの動画変換アプリなんですね.
違います。

> ソースを見て参照方法を探れということですね?
違います。

> これも方法の一つとしますが時間がかかるので,なにか他の方法はないでしょうか?
規格書読むより時間掛かりませんよ。

366:デフォルトの名無しさん
08/06/24 16:10:28
classのstaticメンバで、shortの配列があります。
例えば、
class hoge {
private:
 static array[100];
};
となっていて、arrayの中身を
for(int i=0; i<100; i++){
 array[i] = i*i;
}
のように初期化したいとします。
このよな作業はどの箇所で行えばいいでしょうか。

367:デフォルトの名無しさん
08/06/24 16:16:38
>>366
クラスの外で一回やっておけばよい。
main()が呼ばれる前に初期化される保証がある。

368:デフォルトの名無しさん
08/06/24 16:19:15
Singletonの問題のようにも思えるが

369:366
08/06/24 16:27:24
>>367
GCCですが、.cxxの先頭でやると怒られます。

src/hoge.cxx:24: error: expected unqualified-id before ‘for’
src/hoge.cxx:24: error: expected constructor, destructor, or type conversion before ‘<’ token
src/hoge.cxx:24: error: expected constructor, destructor, or type conversion before ‘++’ token

24: for(int i = 0; i < 100; i++){


370:デフォルトの名無しさん
08/06/24 16:28:58
#include <iostream>

class hoge {
private:
static int array[100];
static int flag;
public:
hoge() {
if (flag) {
for (int i = 0; i < 100; i++)
array[i] = i * i;
flag = 0;
}
}
void printa() const {
for (int i = 0; i < 100; i++)
std::cout << array[i] << ' ';
}
};

int hoge::flag = 1;
int hoge::array[100];

int main()
{
hoge h;

h.printa();
}


371:366
08/06/24 16:31:18
short* hoge::array = 0;

としておいて、constructorで
if(!array){
 array = new short[100];
 for(int i=0; i<100; i++){
  array[i] = i*i;
 }
}

でしょうか。それだと、いつdeleteするのでしょうか。
それとも、初期化フラグをメンバ変数に持っておいて、
それのtrue/falseでconstructorからfor文を呼び出す?

372:366
08/06/24 16:32:03
>>370
ということのようですね。
ありがとうございました。

373:デフォルトの名無しさん
08/06/24 17:22:54
どんな初期化をするかにも夜
コンストラクタとデストラクタは忘れないであげてくだちぃ

374:デフォルトの名無しさん
08/06/24 17:54:53
>>373
staticだからこの場合は無理なのよ

375:355
08/06/24 18:33:23
ffmpegのAPIを使ってMPEG2を読み込めということでしょうか?
現在mpeg2dec-0.4.1 とでどちらを使うか考えています.

両方の向き不向きについて何か教えてくれませんか?

376:デフォルトの名無しさん
08/06/24 18:49:21
C++相談室

377:355
08/06/24 19:53:12
すみません.
そうでした.完全にスレ違いになってしまいました.
去ります

378:デフォルトの名無しさん
08/06/25 00:49:33
C++って先頭からコンパイルしますよね

だから↓はコンパイルエラーになりますよね。
void main(){
int a=func(3);
}
int func(int x){
return x+5;
}

なのに、なぜ↓はコンパイルエラーにならないんでしょうか?
class cA{
public:
cA(){a=10;}
private:
int a;
};


379:デフォルトの名無しさん
08/06/25 00:50:14
C++って、単純な速さは他の言語と比較してどうなの?

380:デフォルトの名無しさん
08/06/25 00:56:45
>>378
そういう仕様に決まったから。

>>379
書き方や問題領域で当然変わってくるけど、大体Cと同じ。

381:デフォルトの名無しさん
08/06/25 00:58:44
ていうことは、C++のコンパイラは場合によっては、
読む場所を行ったり来たりしうるんですね
ありがとうございました

382:デフォルトの名無しさん
08/06/25 02:00:09
>>378
正確に述べると、クラス定義の中に関数定義を書くと、
そいつはクラス定義の終わった後に、inline付で定義されたものとして扱われるということになる。

383:デフォルトの名無しさん
08/06/25 02:15:49
クラス宣言じゃないのか。

384:デフォルトの名無しさん
08/06/25 07:37:29
定義。

385:デフォルトの名無しさん
08/06/25 07:51:00
クラス宣言って外部でメンバ関数の定義をしたりあと前方宣言
の時に使われる物?

386:デフォルトの名無しさん
08/06/25 08:26:28
クラスそのものを後方定義というやり方にも使う。

387:デフォルトの名無しさん
08/06/25 09:26:57
template<typename T> struct base{
 typename T::X test(){ return typename T::X(); }
};

struct A : base<A>{
 struct X{}
};

継承するクラスのテンプレートに継承するクラス自身を渡して、
継承するクラス内の型を基底型で使いたいのですが不可能でしょうか?

388:デフォルトの名無しさん
08/06/25 10:55:21
>>387
全く問題ない。

389:デフォルトの名無しさん
08/06/25 11:27:40
>>387
弾かれました


template<typename T> struct base{
 typename T::X test(){ return typename T::X(); } <-error C2039: 'X' : 'A' のメンバではありません。
};

struct A : base<A>{
 struct X{}
};

390:デフォルトの名無しさん
08/06/25 13:48:24
struct X {};
struct A { void add( X* x ); };

X* x = new X;
A a;
a.add( x );

A のオブジェクトは A::add() で追加した X のオブジェクトを delete する義務があります。
この場合 A::add() が失敗して例外を投げるとき A::add() は x を delete するべきでしょうか?

普通、関数が例外を投げるときその関数が何もしなかったことにするのが理想だと思いますが
delete したほうが便利な場合も多いと思うのですが。

391:デフォルトの名無しさん
08/06/25 14:02:32
すべきでないと思う
auto_ptrを使えばどうか

struct A{ void add(std::auto_ptr<X> x); };

std::auto_ptr<X> x(new X);
A a;
a.add(x);

392:デフォルトの名無しさん
08/06/25 20:30:13
>>390
391に同意。
a.add(x)に渡すxはnewしないといけないという変な制約が発生してしまうから。

393:デフォルトの名無しさん
08/06/25 20:45:33
boost の shared_ptr のコンストラクタや ptr_container の追加関数は
確か失敗したら delete される設計になってた。

394:デフォルトの名無しさん
08/06/26 02:56:30
>>390
そのインターフェースなら a.add(new X) したくなりそうだから、 delete したほうがいいと思う。

395:デフォルトの名無しさん
08/06/26 20:01:08
>>393
スマートポインタと一緒にしちゃだめでしょ。

>>394
X x;
a.add(&x)で落ちてもいいんだね。

396:デフォルトの名無しさん
08/06/26 20:08:30
>>395
boost::ptr_vector

397:デフォルトの名無しさん
08/06/26 20:27:03
C++で動く、フリーなライセンスの行列演算ライブラリはありませんか?

398:デフォルトの名無しさん
08/06/26 21:13:04
boost


399:デフォルトの名無しさん
08/06/26 21:34:13
boost::uBLASな

400:デフォルトの名無しさん
08/06/27 00:34:47
boost::uBLASってパフォーマンスより安全性とかを優先してて遅いとか、
書かれてるけど、実際どうなん?

401:デフォルトの名無しさん
08/06/27 00:48:54
boost::numeric::ublasは遅くないぞ
パフォーマンス表も書いてある

URLリンク(boost.cppll.jp)

402:デフォルトの名無しさん
08/06/27 01:02:54
liboctaveより遅いけどな

403:デフォルトの名無しさん
08/06/27 01:07:56
そうかもしれんがBlitz++のように途中で更新停止したり
するのが怖い
boostならまずそういう事はないだろうし

404:デフォルトの名無しさん
08/06/27 01:25:54
確かに。メンテされ続ける安心ってのは大事だな。

405:デフォルトの名無しさん
08/06/27 01:56:56
Program Optionsとか放置されてて酷いけどな。
一度使おうとして、あまりにも酷い出来で、ワイド文字対応がなってなかったんで、あきらめた。
内部的には全部マルチバイト文字にしてやがる。
そのため、ワイド文字でデフォルト値とか設定しようとするとコンパイルエラー。
少しいじって、utf16からutf8に変換するようにしてやれば動くが、
わざわざそんなことするぐらいなら、自前で書いたほうがいい。

ありゃ絶対に、一文字は絶対に一バイトで、しかも7bitに収まるって前提の南蛮人の書いたコードだ。

406:デフォルトの名無しさん
08/06/27 02:19:23
progressbarは?

407:デフォルトの名無しさん
08/06/27 03:59:44
>>401
ありがとうございました。
ありがとうございました。
ありがとうございました。

408:デフォルトの名無しさん
08/06/27 07:53:35
>>395
> A のオブジェクトは A::add() で追加した X のオブジェクトを delete する義務があります。
これが前提じゃないのか? new してないものは最初から渡せないだろ。

409:デフォルトの名無しさん
08/06/27 08:08:55
「渡せない」と「渡さない」の違い

410:デフォルトの名無しさん
08/06/27 09:33:28
すみません。boost::numeric::ublasを教えていただいた者ですが、
vc8でdebugモードとreleaseモードで結果が異なり、debugモードでのみ正常に動作します。
使用しているboostは1.34ですが、これにはバグがあるんでしょうか?
面倒なのでアップデートしたくないのですが・・・。
boostコード中で警告4267と4244が出てくるのでboostが原因かもしれませんが把捉しかねる状態です。
ご教示願います。

411:デフォルトの名無しさん
08/06/27 10:59:43
URLリンク(engineering.meta-comm.com)

1.34.1で悪いけど。
結構厳しいね。

412:デフォルトの名無しさん
08/06/27 12:45:56
>>397
俺はliboctave使ってたよ
もう遅いかもしれないけど…

413:デフォルトの名無しさん
08/06/28 21:07:42
C++ 始めたばっかなんですが、
this はなんでポインタなんでしょうか
せっかく参照というものがあるのに...

そんで、今日は C++ のオブジェクトが自身への参照を
self という名前で持てるようにいろいろがんばってました。

具体的には、そのクラスを継承したらクラス定義の中で self が使えるようなクラスを作ろー...と思ってたんですが、うまくいかず。
結局
#define self (*this)
しか思いつきませんでした orz

こういうんじゃなくって、ちゃんと自分自身への参照をメンバ変数にもつオブジェクトは作れないのでしょうか。

414:デフォルトの名無しさん
08/06/28 21:18:51
>>413
別の表記方法がないなら*thisでいいじゃん。表現に揺らぎがなくて結構なことじゃないか。同じものをいろんな名前で表現させるほうが混乱するんでないかい?
size length len count distance 同じ意味だったり違った忌みだったり混乱するね。

415:デフォルトの名無しさん
08/06/28 21:25:04
>>413
昔、this = malloc(1); てな構文があったんだよ

416:デフォルトの名無しさん
08/06/28 21:29:05
>this はなんでポインタなんでしょうか
thisが C with Classes に導入されたときには参照はまだなかった

417:デフォルトの名無しさん
08/06/28 21:31:11
JavaからC++への移行は推奨しません。

418:デフォルトの名無しさん
08/06/28 21:47:59
selfってことはJavaじゃないと思う

419:デフォルトの名無しさん
08/06/28 21:50:43
Object Pascalだね。


420:デフォルトの名無しさん
08/06/28 21:51:42
C++ではboostはデフォなのか?

421:デフォルトの名無しさん
08/06/28 21:51:52
現代版#define BEGIN {ですね、わかります。

422:デフォルトの名無しさん
08/06/28 21:58:28
>>420
一部はデフォになりつつある。

まあ、知って損はない。俺も最近使い始めた。今まで知らなくてずいぶん損したと思う。

423:デフォルトの名無しさん
08/06/28 21:59:31
>>420
中にはそういう人間もいる(俺もその1人だがな)。
当然、すべての人間にとってそうとは限らない、いつだって使えるとは限らないから、
Boostデフォを妄信するのは危険。使えないときは反動でだるくなる。

424:440
08/06/28 22:49:03
>442
勉強しておくよ。
GCとか便利そうだし

>443
仕事の場合だと、使えない場合が多そうだな。



425:デフォルトの名無しさん
08/06/28 22:50:24
今テレビでターミネーター2やってるよね。
未来から来たって話。

426:デフォルトの名無しさん
08/06/28 22:59:36
>>424
440基準でも未来レスかよw

427:デフォルトの名無しさん
08/06/28 23:01:52
Testってクラス書くとして

Test.cppとTest.h用意?
Test.cxx作ってそこに全部記述?



428:デフォルトの名無しさん
08/06/28 23:02:56
Testを他で使うなら.hも作っとけ

429:デフォルトの名無しさん
08/06/28 23:05:05
Test.hppにテンプレートクラスでイナフ

430:デフォルトの名無しさん
08/06/28 23:11:42
hppだとどういうコーディングルールがベスト?
サンプルないかな?

431:デフォルトの名無しさん
08/06/28 23:14:01
boost

432:デフォルトの名無しさん
08/06/28 23:14:07
>>426
意味不明だよ。


433:デフォルトの名無しさん
08/06/28 23:15:01
IDテスト

434:デフォルトの名無しさん
08/06/28 23:16:10
>>430
hppでの例
URLリンク(www.boost.org)

ベストかどうかは・・・分からんけど。

435:デフォルトの名無しさん
08/06/28 23:17:05
>>432

424 :440 [sage] :2008/06/28(土) 22:49:03
  >442
  勉強しておくよ。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

4766日前に更新/209 KB
担当:undef