■過去ログ置き場に戻る■ 1- 前250 次250 最新50


[memo] "9999999999_00.html#R20" という感じで、URLの最後に "#RレスNo" を追加すると幸せになれます。

C++相談室 Part4
501 名前:デフォルトの名無しさん :02/01/18 01:15
Giko a;  <-デフォルトコンストラクタ
Giko b = a;  <-コピーコンストラクタ
= a;  <-代入演算子

502 名前:デフォルトの名無しさん :02/01/18 02:56
>>501 追記
Giko b(a); <-コピーコンストラクタ
Giko b[3]={
 Giko(1),
 Giko(2),
 Giko(3),
} <-デフォルトコンストラクタ

503 名前:デフォルトの名無しさん :02/01/18 03:15
>>502
どうせなら return とか throw の例も書いたほうが。

504 名前:デフォルトの名無しさん :02/01/18 07:06
えっと質問です。
あるクラス Base を継承した Sub クラスを作りました。
また別に、同じく Base を継承した SubKitajima クラスを作りました。

プログラム中で
Base へのポインタを宣言して、
状況によって Sub か SubKitajima のインスタンスを生成するように
しました。

で、このインスタンスを削除しようとしたのですが…。
delete した時に呼び出されるのは Base のデストラクタだけでした。

この場合、Base へのポインタを通して、正しく Sub か SubKitajima の
デストラクタを呼び出すにはどうしたらいいのでしょうか?
よろしくお願いします。


505 名前:デフォルトの名無しさん :02/01/18 07:14
>>504
デストラクタを仮想関数にする。
>>495
可能性はあるだろうが・・・しないだろうな、普通は。
>>493
同意。
>>489
ええと、488の例でCのメソッドを呼ぶときは、必要に応じてアドレスをずらしたthisを渡すはずです。
仮想継承の場合は良く知らんのでパス。

506 名前:504 :02/01/18 07:19
>>505
うまくいきました。
ありがとうございますー。

507 名前:506 :02/01/18 07:38
うまくいったと思ったのですが…。
ひとつちょっと疑問が…。

デストラクタは純粋仮想関数にできないのでしょうか?コンパイルは通ったのですが、リンカが「外部シンボルが見つからない」と
言ってくるのですが。

508 名前:デフォルトの名無しさん :02/01/18 08:46
>>506
基底クラスのデストラクタはきちんと実行される必要があるので純粋仮想関数にはできないよ。

509 名前:387 :02/01/18 09:07
>>484
 うーん。そういう実装なんでしたら、やっぱり1.の方がいいようです。
俺が考えた1.の設計の具体案はこうです。

// IGraphicBuffer.h
class IGraphicBuffer
{
    // グラフィックバッファ(実装は省略)
}

// CBitmapLoader.h
class IGraphicBuffer;// 前方宣言
class CBitmapLoader
{
public:
    static bool Load(IGraphicBuffer&,const string&);
}

// CGraphic.h
class IGraphicBuffer;// 前方宣言
typedef bool (*LOADFUNC)(IGraphicBuffer&,const string&);
class CGraphic
{
public:
    CGraphic();
    static vector<LOADFUNC> m_pLoaders;
    bool Load(cosnt string&);
private:
    auto_ptr<IGraphicBuffer> m_pBuffer;// バッファ本体
}

// CGraphic.cpp
#include "IGraphicBuffer.h"
CGraphic::CGraphic :
    m_pBuffer(new IGraphicBuffer)
{
}
bool CGraphic::Load(cosnt string&)
{
    for (vector<LOADFUNC>::iterator i = m_pLoaders.begin(); i != m_pLoaders.end(); ++i)
        if ((*i)(*m_pBuffer,file))
            return true;
    return false;
}

 関数ポインタの取り扱いだけはちょっと不安がありますが。その問題点を除けば、
仮想関数も継承も不要で、クラス依存性は極めて小さくなります。
 特に、メインルーチンで動的にローダー登録を行うところでは、
CGraphic.hとCBitmapLoader.hをincludeして、

CGraphic::m_pLoaders.push_back(CBitmapLoader::Load);

 と書くことになりますが、この書き方だと、IGraphicBufferを変更しても、
このメインルーチンをコンパイルし直さなくてもすみます(よね?)。
 と、ここまで依存性を減らせるとわかったから、さすがに「thisを渡さないで」
などとワガママいってる場合じゃないなと思って、1.の設計でいこう、と
決めました。これ以上の設計って、なにかあります?
 ところで、>>478ではtypedefをクラス内で行ってますけど、
そう記述すると、そのtypedefはクラス内だけで有効なんですかね?


510 名前:デフォルトの名無しさん :02/01/18 10:56
>デストラクタは純粋仮想関数にできないのでしょうか?

できませんよ。ていうか、そうする必然性ってあるの?

511 名前:デフォルトの名無しさん :02/01/18 10:58
VC6.0のSTLで質問です。
STLを使うと、MSVCP60.DLL が必要なんですか?
自分の開発マシンでは当然Systemフォルダに入ってるんですが、
入ってない人もいた。
XpとかMeあたりだと初期状態であるんですかね?


512 名前:デフォルトの名無しさん :02/01/18 11:24
先生方、教えてください。
テンプレートクラスのメンバ関数ポインタを保持することは可能でしょうか?
「オブジェクトに付随した形式のメンバー関数のポインタを取り出そうとしている」と
エラーが出たのですが、回避する方法は無いものかと。


513 名前:日下部圭子 ◆ib749tYo :02/01/18 11:27
In article >>510, デフォルト名無しさん/510 wrote:

> >デストラクタは純粋仮想関数にできないのでしょうか?
> できませんよ。

VC++6では、デストラクタも純粋仮想関数にできるようです。
これはVC++6の仕様がおかしいのでしょうか?

----------------------------------
||//
(@_@) Kusakabe Keiko
----------------------------------

514 名前:デフォルトの名無しさん :02/01/18 11:32
>>511
ランタイムライブラリをスタティックリンクにすれば
MSVC*.DLLは不要です。
ただしヒープが共有できないので、DLL/EXE間でSTL
オブジェクトの受け渡しは事実上不可能になります。
単体のEXEなら問題ない。


515 名前:511 :02/01/18 12:12
>>511
ということはコード生成で、使用するランタイムライブラリが
マルチスレッド(DLL)だと駄目ってこと?


516 名前:ぱふーん ◆BEVSNet2 :02/01/18 12:40
>>510,513
「C++ FAQ」のFAQ21.13を参照すべし

class Base {
public:
virtual ~Base() throw() = 0;
}

inline Base::~Base() throw() { }

とinlineの併用でできるらしい。
なんや、ようわからんけど


517 名前:デフォルトの名無しさん :02/01/18 13:01
>>515
マルチスレッドか否かは関係ないです。
/MD ならMSVC*.DLLが必要
/MT や /ML なら不要
ということ。

518 名前:462 :02/01/18 13:08
ありがとうございました。
もう少し考えてみます。。

519 名前:デフォルトの名無しさん :02/01/18 15:21
>>516
抽象クラスを作りたいんだが、どうしても純粋仮想関数にするメソッドが見当たらない場合に
使うことはある。

520 名前:デフォルトの名無しさん :02/01/18 15:29
>>509
その設計だと CBitmapLoader::Load は static メソッドになるの?

521 名前:387 :02/01/18 16:13
>>520
 そうです。CBitmapLoader::Load は、ファイルネームを受け取って、
IGraphicBufferのオブジェクトに適切なデータを格納するだけですから。
端的に言うと、strcpy(Dest,Src)みたいな機能ですので、staticです。


522 名前:デフォルトの名無しさん :02/01/18 16:24
>>521
そこで設計のトレードオフが発生してるわけだ。

ローダに柔軟性を求めないなら、それで良いんじゃない。

523 名前:C++消防 :02/01/18 16:28
こんなこと可能でしょうか?

template <typename T1>
class hoge
{
---
hoge<T1> &operator *= (???);
}

emplate <typename T1, typename T2>
hoge<T1> &hoge<T1>::operator *= (T2 &hogehoge) // 行列×=複素数
{
---
}

用はオーバーロード*=の引数に別のテンプレートを使いたいのですが
この場合???のところ(というかテンプレートクラス全体)を
どのように書けば実装できますか?

あるいは不可能なのでしょうか...

524 名前:C++消防 :02/01/18 16:29
あ,コメント文消すの忘れた

鬱山車嚢

525 名前:C++消防 :02/01/18 16:34
しかも
用→要
UTUDASINOU

526 名前:デフォルトの名無しさん :02/01/18 16:42

template <typename T1>
class hoge
{
---
 template<typename T2>
 hoge<T1> &operator *= (T2 &rhs)
 {
  ....
 }
};

ではあきまへんか?

527 名前:387 :02/01/18 17:42
 CGraphic::Loadではiteratorを使っている以上、関数の柔軟性に
関しては>>484>>521も同じではないんですか? トレードオフには
なってないと思いますけど…。


528 名前:C++消防 :02/01/18 17:50
>>526
ありがとうございます,やってみます.

529 名前:デフォルトの名無しさん :02/01/18 17:57
いや、staticになっているのがトレードオフじゃねーの?
インスタンスがとれないなら、Cの関数と変わらない、つーか。



530 名前:デフォルトの名無しさん :02/01/18 18:13
>>527
まぁ設計は

 こちらをたてれば
  あちらがただず

で、何を重視するかで選択が違ってくる。後々を考えると >>484>>521 には差が出てくる場合がある
けど、それが重要ではない(少なくとも現時点で利用法を考えたときに差が見えない)なら、キミの用途
にとっては、どちらも OK ってことだと思うよ。

いずれにせよ、事前の設計で 100% 完全なものを見通すのは難しいから、そろそろ実装に移って良いと
思うよ。設計ミスが判明したら、その時点で何が悪かったのか良く考えて設計しなおし、ってことを何度
かやる内に身体にバランス感覚が染み付く。

531 名前:387 :02/01/18 18:16
>>529
 そうはいっても、>>484のロード関数だって、機能的には
static同然ですよ。やってる内容はstrcpy(Dest,Src)です。
ただ、仮想関数のオーバーライドだからstatic宣言できないだけで。
むしろ、実体のないインスタンスを生成する無駄があるのでは…?

 あれ、いや、俺、なんか勘違いしてますかね?


532 名前:デフォルトの名無しさん :02/01/18 18:36
> そうはいっても、>>484のロード関数だって、機能的には
>static同然ですよ。やってる内容はstrcpy(Dest,Src)です。
 だからといってクラスメソッドにすると、ロードオブジェクトとして、
何か変数/状態を持ちたい、とかに対応でなくなるだろう。
そこがトレードオフなわけよ。
 530が言ってるとおり、その「ロード関数」がstrcpy(Dest,Src)同然
の事しかしないから、387はそれが有利なトレードと判断したんだろう?


533 名前:387 :02/01/18 19:03
>>532
 な・る・ほ・ど〜。ものすごく納得できました。ありがとうございます。

 とりあえず、>>530さんの忠告どおり、そろそろ実装に入ります。
>>387から、長長とお付き合いありがとうございました。

 お礼と言っては何ですが、マ版のオナペットスレに、俺のお気に入りの
高画質フリーアダルトムービーのアドレスを書いておきますね。


534 名前:デフォルトの名無しさん :02/01/18 19:23
>>533
>  お礼と言っては何ですが
個人的にはその手の画像より、ソースコードの方が萌えます(ぉ

535 名前:デフォルトの名無しさん :02/01/18 19:54
>>519
> >>516
> 抽象クラスを作りたいんだが、どうしても純粋仮想関数にするメソッドが見当たらない場合に
> 使うことはある。
純粋仮想関数にする面罵関数は無いけど抽象クラスである必要があるケースってどんなでしょう?
単純に興味本位の質問です。

基底クラスの実体を作らせたくなかったら構築子を protected にすればすむし…
基底クラスのポインタで一元管理し、必要に応じて dynamic_cast したい?


536 名前:デフォルトの名無しさん :02/01/18 19:59
>>513
> > >デストラクタは純粋仮想関数にできないのでしょうか?
> > できませんよ。
>
> VC++6では、デストラクタも純粋仮想関数にできるようです。
> これはVC++6の仕様がおかしいのでしょうか?
おかしいのは“あんたの”VC++6か、あんたの文章読解能力だろ(w

デストラクタが純粋仮想関数のクラスも定義はできる。
それを継承したクラスの実体を生成しようとすると、
リンクエラーとなる、って話を507はしてんだろ?


…513のHNを見ると、刺々しいレスを付けたくなるよう(笑


537 名前:デフォルトの名無しさん :02/01/18 20:47
>>535
仮想関数はあるが、純粋仮想関数にするものが無い場合と思われ。

538 名前:デフォルトの名無しさん :02/01/18 20:48
インタアフエイスには、純粋仮想関数がよく似合ふ

539 名前:デフォルトの名無しさん :02/01/18 20:50
>>537
それは“抽象クラスを作りたい”理由にはならないのでは?

540 名前:デフォルトの名無しさん :02/01/18 20:55
> 抽象クラスを作りたいんだが、どうしても純粋仮想関数に
> するメソッドが見当たらない場合に使うことはある。
邪悪な設計ですね。

541 名前:519 :02/01/18 21:07
>>535
> 基底クラスの実体を作らせたくなかったら構築子を protected にすればすむし…
そう書く代わりにデストラクタを純粋仮想にする、ってだけ。

542 名前::02/01/18 22:10
諸君あけおめことよろ。なんて。
ようやくMore Exceptional C++を読み始めたわけなのですが
例の、Effective STLでは保証されていると断言されているのに
標準には見あたらないvectorのメモリレイアウトのことですが
This was fixed in 2001 as part of Technical Corrigendum #1
to the C++ standard.だそうです。よかったね。
Schemeに夢中なのでレビューは一ヶ月後かも。

543 名前:507 :02/01/18 22:16
うわ、日中みないうちにたくさんの方にレスして貰ってる…。
みなさんありがとうございます。

実は Java のコードを C++ に移植していた所で、
Java の interface にあたるクラスを作ろうとしていた所でした。

というわけで、ベースクラスのデストラクタで、特に処理する事は
なかったのです。
こういう場合は、デストラクタが必要なサブクラスの為に
空っぽの仮想デストラクタを定義するといいみたいですね。

みなさんありがとうございました。


544 名前:デフォルトの名無しさん :02/01/18 22:44
>>507
純粋仮想として宣言できますが、しかし実装も書かないとダメです。

545 名前:デフォルトの名無しさん :02/01/18 22:52
>>544
実装があったら純粋仮想関数ではなく仮想関数

546 名前:デフォルトの名無しさん :02/01/18 23:01
=0 が付いてたら純粋仮想だろ?実装があっても。

547 名前:デフォルトの名無しさん :02/01/18 23:13
>>546
試して理解しました
知らんかったのよ
純粋仮想関数として定義しつつ実装もするって手法
許して

548 名前:デフォルト :02/01/19 03:03
MFC+VCで質問です。
ダイアログボックスベースのプログラムで
自分で作ったほかのクラスから
一番上のウインドウハンドル
m_hWndを得るにはどうしたら良いでしょう?
CxxDlg::GetSafeHandle
したり
CxxDlg::m_hWnd
したり
よくわからないままいろいろしてるのですが、どれもうまくいきません。
初心者カキコです。すまんです。



549 名前:デフォルトの名無しさん :02/01/19 03:13
>>548
すれ違い。こっちで聞いて。

■ VisualC++(MFC限定)相談室 2■
http://pc.2ch.net/test/read.cgi/tech/1008031675/


550 名前:デフォルト :02/01/19 03:21
>549
すみません。そっちにいきます

551 名前:C++消防 :02/01/19 08:32
任意の型,任意の数の引数を受ける関数を作りたいのですが
va_arg を使うためには予め型を知っている必要がありますよね.

"%d %f" のような型情報を一緒に送れば確かにできますが
これ無しで組むことは可能でしょうか?

typeidを使ってごちゃごちゃやってみたんですが
なかなかうまくいきません...鬱鬱

552 名前:デフォルトの名無しさん :02/01/19 08:53
>551
まず,本当にそういう関数が必要なのか自分自身に問い詰めろ
小一時間問い詰めろ
話はそれからだ

553 名前:C++消防 :02/01/19 09:13
n次元ベクトルがそれぞれ型の違う複数の要素を持つとします.
その要素をファイル出力する場合に

要素1[1] 要素2[1] 要素3[1] ...
要素1[2] 要素2[2] 要素3[2] ...
要素1[3] 要素2[3] 要素3[3] ...

と表示したいのですが,出力したい要素の並び,内容が
頻繁に変わるので,一々型を指定しなくてもよくなれば
楽になるかと思ったのですが...

554 名前:デフォルトの名無しさん :02/01/19 09:27
型情報と格納メモリをさすポインタをいれた構造体をつくれば何とかなるでしょ

555 名前:デフォルトの名無しさん :02/01/19 09:30
わからんな。一個づつ std::cout << vect[k][i] ;
とかすればいいのではないのか?

556 名前:C++消防 :02/01/19 09:43
>>554
なるほど,そんな手がありますか

>>555
fileout("ファイル名", vector<T1> a, vector<T2> b ...);
(T1, T2, T3は型が違う)

と書けば
a[1] b[1]...
a[2] b[2]...
.
.
.

の内容のファイルが自動的に生成されるような関数を作りたいのです.

557 名前:デフォルトの名無しさん :02/01/19 09:48
解決法が無い訳じゃないと思うが(templateを使いまくれば…)
その前に設計を考え直した方がいいと思う。

558 名前:デフォルトの名無しさん :02/01/19 09:53
だから、なんで、
class fileout{
fileout(const string &filename)
operator ()( T hoge )
}
for_each( a.begin(), a.end(), fileout( "filename" ) )
for_each( b.begin(), b.end(), fileout( "filename" ) )
みたいにしないわけ?

559 名前:デフォルトの名無しさん :02/01/19 09:58


560 名前:C++消防 :02/01/19 10:20
>>558
出力がExcelで見やすいように「列」に並べたいのですが
その場合,同じ型の要素が「行」で並びませんか?
消防なもので意図がうまくつかめなくてすいません.

561 名前:デフォルトの名無しさん :02/01/19 10:42
どーでもいいけど配列インデックスは 0 から書こうぜ


562 名前:デフォルトの名無しさん :02/01/19 10:47
>>560
だったら「列」で並ぶような配置の vector を持てば良いでは無いか.

563 名前:C++消防 :02/01/19 10:53
>>561
確かに.

>>562
いえ,vector自体には列も行もなくって次元の情報しかありません.
問題はファイル出力のときに

a[1] b[1]...
a[2] b[2]...
...

となるか

a[1] a[2]...
b[1] b[2]...
...

となるかです.



564 名前:デフォルトの名無しさん :02/01/19 11:04
>>563
んあ?
> vector自体には列も行もなくって
で,
> 同じ型の要素が「行」で並ぶ
んなら,列で並べるのに何の苦があるんだ?
行と列の区別無いんだろ?
インデックス値をちょっとイヂるだけじゃねーのか?

ちょっとデータ構造をきちんと書いた方がいいと思われ



565 名前:デフォルトの名無しさん :02/01/19 11:13
for( int i=0; i<N; i++ )
{
print_dat( fp,a[i] );
print_dat( fp,b[i] );
print_dat( fp,c[i] );
...
}
と並べていくのは嫌だ、という話か?

566 名前:C++消防 :02/01/19 11:17
えーと...

>>565
だと

a[1] a[2]...
b[1] b[2]...
...

となってしまいますよね?

a[1] b[1]...
a[2] b[2]...
...
のように表示したいのですが.


567 名前:デフォルトの名無しさん :02/01/19 11:30
ならねーよ。よくかんがえてみろ。
print_datは一回に一つしか表示しない。
print_dat(fp,z[i]);のあとに、
print_dat(fp,"\n");でも入れれば判るか?

568 名前:デフォルトの名無しさん :02/01/19 11:31
>>565 じゃないけど,>>565 のやり方なら後者になると思うが.

569 名前:568 :02/01/19 11:31
シマッタ、カブッタ・・・ウツシ

570 名前:デフォルトの名無しさん :02/01/19 11:36
>>566
>>565 だと、
a[1] b[1]...
a[2] b[2]...
...
になると思われ。

でもさ、要するに、
は A 型、 b は B 型、 c は C 型のベクターだとするわな。
そうすると、
a[1] b[1]...
a[2] b[2]...
...
っていう風に並べたいときって普通は、
struct Tuple
{
A a; B b; C c;
};
ostream& operator<< (ostream& os, Tuple tupple)
{
os << tupple.a << " " << tupple.b << " " << tupple.c;
return os;
}
って構造体作って、Tuple 型のベクター使わんか?


571 名前:C++消防 :02/01/19 11:37
>>567
御手数おかけします.
おそらく言わんとしていることがわかりました.
要は,行が変わる度にファイルポインタを行の最後に
持って来ればいいんですね?
要素が変わった場合はまたポインタを一番前に戻すと.

確かに行の最後の位置をインデックス配列に保存すれば
ポインタをいじる方がよっぽど簡単ですね.


572 名前:C++消防 :02/01/19 11:41
>>570
ファイルアウトしたい要素が頻繁に変わるので
(又,後々何度も使いそうなので)
struct Tuple を書き直すよりも引数で指定できれば楽かなと思いました.
(また見当違いなことを言っているかもしれないです)



573 名前:デフォルトの名無しさん :02/01/19 11:42
ファイルポインタはいぢっていないよーな・・・

574 名前:デフォルトの名無しさん :02/01/19 11:44
じゃさ。これだったらわかるか?
for( int i=0; i<N; i++ )
{
std::cout
  << a[i] << ", "
  << b[i] << ", "
  << c[i] << "\n";
}
ああ、今回はデリミタはなしだが

575 名前:C++消防 :02/01/19 12:04
>>574
Fileout関数を一つのソースの中で複数の場所から呼んでいます.
しかも型情報も引数の数もNの値も違います.となるとファイル出力の度に
for(...) {
...
}
を書く必要がありますよね.そこを簡単に
Fileout("ファイル名", vector<T1> v1,vector<T2> v2..);
とすればNの値を N = v1.GetDimension() で取得して
書き出すようにしたかったんです.

576 名前:デフォルトの名無しさん :02/01/19 12:07
template< class T, class U , class V, class W,class X,class Y,class Z >
Fileout( const char *s, T& t, U &u, V &v, W &w, X &x, Y &y, Z&z )
{
}
でもツカットケ。

577 名前:デフォルトの名無しさん :02/01/19 12:14
さすがに576は不親切だった。反省している。
class EmptyClass {};

template< class T, class U=EmptyClass , class V=EmptyClass, class W=EmptyClass,class X=EmptyClass,class Y=EmptyClass,class Z=EmptyClass >
class Fileout{
public:
 Fileout(const char *s){}
 operator ()( T* t, U *u = NULL, V *v = NULL, W *w = NULL, X *x = NULL, Y *y= NULL, Z *z = NULL)
 {   int N = t->dimension(); for(...) }
};

int main()
{
 int a, b ,c;
 Fileout<int,int,int> fo( "tmp" );
 fo( &a, &b, &c );
}

こんなところでどうよ?

578 名前:C++消防 :02/01/19 12:29
なるほど,ありがとうございます.
引数はせいぜい4〜5個なので十分間に合います.

579 名前:デフォルトの名無しさん :02/01/19 18:44
けつが痛い

580 名前:デフォルトの名無しさん :02/01/20 01:17
質問させてください。
下のプログラムで(*2)のようにインスタンスを生成しようとすると
VC++6ではコンパイル時にエラーが出ます。(*1)がなければ大丈夫です。
この例自体にはあんまり意味はないんですが少し気になったので・・・。
どなたか理由判りませんか?

class Foo {
public:
 template<typename T> class HogeBase; // (*1)これがあると駄目らしい
 template<typename T> class HogeBase {}
 typedef HogeBase<int> Hoge;
};

int main()
{
Foo::Hoge hoge; // (*2)
return 0;
}

--
http://pc.2ch.net/test/read.cgi/tech/1010673275/412-


581 名前:デフォルトの名無しさん :02/01/20 02:33
>>580
そりゃ、VC++の template の実装があまいから。
メンバテンプレートの使えないし。


582 名前:511 :02/01/20 13:16
>>511

MSVCP60.DLLを自分のアプリと一緒に配布してもOK?
インストーラは使わないで、ZIPで配布です。


583 名前:デフォルトの名無しさん :02/01/20 13:27
>>582
redist.txt

584 名前:デフォルトの名無しさん :02/01/20 13:35
テンプレートの明示的特別化と
部分特別化の違いがよくわかんないです。
どこがどのように違うのでしょうか?

585 名前:デフォルトの名無しさん :02/01/20 20:26
squidのログのように、各エントリが可変長で、なおかつ全体をメモリにロードできない
ぐらい巨大なものをソートするには、どんなアルゴリズムを使えばいいのでしょうか。
データにランダムアクセスできないのでほとんどのソートアルゴリズムは使えませんよね。



586 名前:デフォルトの名無しさん :02/01/20 20:37
>>585
なんだかアルゴリズムの教科書に出てきそうな問いだな。

マージソートでいいんじゃないの?

587 名前:デフォルトの名無しさん :02/01/20 20:46
>>585
マージソート

たしか 4.4BSD 系の sort って、必要に応じてテンポラリファイルを作ってマージソート
してたような気がする。

588 名前:580 :02/01/21 12:35
>>581
どうもありがとう。
VisualC++が悪いということで納得しました。


589 名前:デフォルトの名無しさん :02/01/21 15:30
ちょっとWindows依存な質問なんですが、
勉強がてらに API だけでお手製クラスライブラリを作ろうと思っています。

で、しょっぱなでいきなりつまづいています。
「Windowsクラス」というのを作って、メッセージの処理をこちらで
やろうと思ったのですが、ウィンドウプロシージャで、どの「Windowクラス」に
メッセージがきた事を伝えればいいのかわかりません。
メッセージループの処理をしているクラスに hWnd の管理テーブルを作って
それで判断するしかないでしょうか?

590 名前:デフォルトの名無しさん :02/01/21 15:47
>>589
それを自分で考えるのが勉強ではないの。ATLのソースでも読めば?

591 名前:589 :02/01/21 15:48
SetWindowLong の GWL_USERDATA に this 入れておけばよかったんですね。
とりあえず自己解決です。ありがとうございました。

592 名前:590 :02/01/21 15:48
ATL->WTL

593 名前:591 :02/01/21 15:49
と思ったら直前にヒント貰ってたみたいですね。
ありがとうございました>>590

594 名前:デフォルトの名無しさん :02/01/21 19:51
>>592
いや、そこは ATL で良い。興味があるなら CWindowImpl あたりから読み進めましょう。

595 名前:デフォルトの名無しさん :02/01/22 00:26
>>584
なんらかの形でテンプレート引数が残っているのが
partial specialization ってだけじゃないの?
テンプレート引数が空になったのが完全な (明示的な?)
specialization



596 名前:デフォルトの名無しさん :02/01/22 01:51
void printfunc(vector<class elemtype> vec, string str)
{
vector<elemtype>::iterator it = vec.begin(), end_it = vec.end();
cout << str;
for (; it != end_it; ++ it) cout << *it << ' ' << endl;
}
このようにvectorクラスをパラメータに渡す関数を作りたいのですが、
vectorの中身がどのような型か分かっていないとパラメータとしては
渡せないのでしょうか?
今の状態だとエラーが沢山でて何のことか分かりません。

597 名前:デフォルトの名無しさん :02/01/22 01:57
template< class T >
void printfunc(T &vec, string str)
{
T::iterator it = vec.begin(), end_it = vec.end();
cout << str;
for (; it != end_it; ++ it) cout << *it << ' ' << endl;
}

598 名前:デフォルトの名無しさん :02/01/22 01:57
>>596

#include <iostream>
#include <vector>
#include <string>
using namespace std;

template<typename T>
void printfunc(const vector<T> &vec, const string &str)
{
vector<T>::const_iterator it = vec.begin(), end_it = vec.end();
cout << str;
for (; it != end_it; ++ it) cout << *it << ' ' << endl;
}

main()
{
vector<int> A;
A.push_back(17);
A.push_back(18);
printfunc(A, "test:\n");
}


599 名前:デフォルトの名無しさん :02/01/22 02:07
>>597-598
めちゃんこありがとうございます。
関数、またはクラスをテンプレートにするんですね。
なんか使い方が少し分かってきました。
見習ってよく勉強したいとおもいます。
ありがとうございました。

600 名前:デフォルトの名無しさん :02/01/22 02:38
g++ 2.95.3だと
T::iterator it = vec.begin(), end_it = vec.end();

typename T::iterator it = vec.begin(), end_it = vec.end();
って書かないとだめなんだけど、誰か解説プリーズ

601 名前:巨額詐欺 :02/01/22 02:48


巨額詐欺の疑いのある、グローバリーについて

掲示板を拝見されてるの皆様、新年あけましておめでとうございます。
掲示板の趣旨とは直接関係ない話で申し訳ないのですが、この世の中では許せない事があります。

http://www.max.hi-ho.ne.jp/sakimono/index.htm

この会社はありもしない儲け話をでっち上げ、巧みに客の財産を聞き出し、全財産を巻き上げます。

2002年になりましたが、一向に改善する気配すらなく、悪質化は進む一方です。
この会社の営業は世間の皆様の迷惑になっています。

それだけではなく、人を騙して破産に追い込み、騙された人が仕方なくグローバリー社員を
殺人する事件も実際に発生し、新聞ザタになっています。

http://www.mainichi.co.jp/news/selection/archive/200001/24/0124e038-400.html

みなさんもこちらの掲示板に投稿し、悪徳会社に騙される不幸な人が増えないようご協力お願いしま
す。


http://messages.yahoo.co.jp/bbs?action=q&board=8745

また、この書き込みを見て賛同頂ける方はこの内容をコピーしていろんな掲示板に書き込みをお願いします。




602 名前:デフォルトの名無しさん :02/01/22 02:52
>>600
そりゃ、例えば、↓みたいに iterator が型でない可能性があるから。
型であるということを明示しないと駄目。

class Type
{
public
int iterator; // iterator が型じゃない
}

template< class T >
void printfunc(T &vec, string str)
{
T::iterator it = vec.begin(), end_it = vec.end();
cout << str;
for (; it != end_it; ++ it) cout << *it << ' ' << endl;
}

int main()
{
Type t;
printfunc(t, "");
return 0;
}


603 名前:596 :02/01/22 03:27
ちなみにg++-2.95.4を使っているんですが、
typename T::iterator it,end_it;
it = vec.begin();
end_it = vec.end();
このように2行に分けて書かないとエラーが出るのは仕様なんでしょうか?

604 名前:596 :02/01/22 04:00
あとそれから、
関数テンプレートというのは皆さんあまり使わないのでしょうか?
クラスをテンプレート化するほうがスマートだと言う感じですか?
上のものは標準入出力を使った関数を少しだけ(デバッグ用に)
テンプレート化しただけですが、これにしてもスーパークラスに
おいて持ってしまえば、関数においてテンプレートにしておく
必要もないですよね?

C++が手続き指向のプログラミングも出来るというメリットの
ためにあるんですよね?

605 名前:596 :02/01/22 04:04
質問バッカですんません。Java房なんてテンプレートに
感動してる最中なもんで(^^;(早くJavaにもテンプレートを!)

606 名前:デフォルトの名無しさん :02/01/22 04:31
>>604
<algorithm>

607 名前:デフォルトの名無しさん :02/01/22 04:41
>596
きみのやりたいことは、関数化しなくても、
std::cout << str;
std::copy( vec.begin(), vec.end(), std::ostream_iterator( std::cout, " \n") );
でやれたはず。

608 名前:596 :02/01/22 04:56
>>606-607
どうもです。
今C++Primerのサンプルコードのみで勉強していますw。
本を持っていないので推測だけで勉強してるのですが、
なかなか思うようには理解が進みません(あたりまえか!?)
今度C++Primerの訳書を買ってちゃんと勉強し直します。

>>606
container type
algorithm type
iterator type
この三つの組み合わせがどうもイメージ出来ないんですよね。難しいです。

>>607
これがSTLですか。
これはC++におけるCの標準関数みたいなものになるのでしょうか?

はやいとこC++覚えてServlet作りまくりの毎日から脱出したいです・・・

609 名前:606 :02/01/22 05:10
>>608
>これがSTLですか。
それは標準アルゴリズムでSTLじゃないよ
ていうか596のJava風引数渡しが、597の回答でさりげなく参照渡し
へ変更されているのにウケタ

610 名前:596 :02/01/22 05:27
>>609他、みなさん。
今日はこんな夜中にいろいろとありがとうございました。
これ以上はチョット恥かしいのでもう書きませんw。
スレ汚して済みませんでした。

611 名前:デフォルトの名無しさん :02/01/22 07:43
>>609
<algorithm> は、STL の一部だと思うが


612 名前:596 :02/01/22 08:01
603の書き込みは嘘でした。
typename T::iterator it=vec.begin(),it_end=vec.end();
としたところ、g++の2.95.4、3.03ともにOK。
何か別のエラーと勘違いしていたようです。
ごめんなさい>g++

613 名前:609 :02/01/22 10:21
>>611
スマソその通り。
>これはC++におけるCの標準関数みたいなものになるのでしょうか?
に対してC++におけるCの標準関数はCスタイルアルゴリズムなんだ! とボケた方がよかった(w
>>612にならって、>>609書き込み前半は嘘でした。
ごめんなさい>596

614 名前:596 :02/01/23 01:59
C++Primer原書を4000円でげっとー、あげ

615 名前:デフォルトの名無しさん :02/01/23 02:13
あるデータを格納するのに
DWORD *num = new DWORD[100];
として使ってるんですけどデータが1桁だったら勿体ないし
100を越える可能性もあるから問題がありますし、、
こういった場合スマートな方法は何ですか?

616 名前:デフォルトの名無しさん :02/01/23 02:15
>>615
std::vector

617 名前:デフォルトの名無しさん :02/01/23 02:46
>>616
ありがとうございます。
これは便利だからといって使いすぎると速度が
低下してしまうかな?

618 名前:デフォルトの名無しさん :02/01/23 02:55
>617
サイズ変更しまくらない限り心配無用だと思われ
# egcs とか古いコンパイラだと遅かったりもするけど

619 名前:デフォルトの名無しさん :02/01/23 03:01
>>617
大量のデータを突っ込むことが事前にわかってるなら reserve() しとくと良いよ。

620 名前:デフォルトの名無しさん :02/01/23 09:00
>>617 色んな型で定義しなければそれほど気にしなくてもいい


しかし >>615 の話なら 単に

入力処理では可能性のある最大桁を取っておいて、
 入力処理の帰り値では そのサイズだけの領域を確保 それにコピー

という手法が適切だろう。 


まあ、最近ならそういうのはデータベースアクセスに置き換えてしまうとか

621 名前:デフォルトの名無しさん :02/01/23 11:14
すみません厨な質問だと思いますが
new 演算子でクラスの配列を割り当てるときは
コンストラクタに引数を渡す事はできないんですか?

622 名前:デフォルトの名無しさん :02/01/23 11:39
new Cls[10](30);
とかじゃダメ?

623 名前:デフォルトの名無しさん :02/01/23 11:47
>622
それだとコンパイルとおらんよ

624 名前:デフォルトの名無しさん :02/01/23 11:56
>>623
g++だとこれでもOKみたいなんです。

勉強始めたバッカなので、
個別にコンストラクタへの
パラメータの設定する方法、
自分も知りたいです。

625 名前:デフォルトの名無しさん :02/01/23 11:59
すまん
VC6だと
とおらんかった

626 名前:デフォルトの名無しさん :02/01/23 12:02
ポインタの配列つくって
いっこずつnewは

627 名前:621 :02/01/23 12:02
>>621 です
今は VC++6.0 でやってます。MSDNや入門書など
見てるのですがどうにもわからないです。
イメージとしてはまさしく >>622さんの書かれたような事を
したいんです。


628 名前:デフォルトの名無しさん :02/01/23 12:10
基本は >>626 だと思うけどね。
どうしても delete Cls[] したいのであれば、初期化用の関数作るとか?
でもかえって手間になるので氏労徒にはお勧めできない。

629 名前:621 :02/01/23 12:45
>>628 さん
はい、今までは 初期化用の関数作って間に合わせていました。
しかし、もしもインスタンス作成後に初期化関数を呼びだすのを忘れると
値の割り当てられていない変数への不正なアクセスを許してしまうのは
OOPL的にいかがなものか、と氏労徒なりに思ってしまって。
自分で使う分にはいいんですが。ドキュメントしっかり書いておけばいいと
いうことででしょうか。
でも >>626 さんのやり方が基本なんですね。やってみます。
ありがとうでした。

630 名前:デフォルトの名無しさん :02/01/23 13:09
誰かこの本を読んだ方はいらっしゃいますか?
【C++ Network Programming Volume 1】
http://www.amazon.co.jp/exec/obidos/ASIN/0201604647/

631 名前:デフォルトの名無しさん :02/01/25 04:46
>>630
読んでないけど目次見る限りACEの解説書だね。ACE使ってクロス
プラットフォーム開発って魅力的な気もするけど実際どの程度
使われてるんだろう。ちなみに俺は乗り気じゃありません。

632 名前:デフォルトの名無しさん :02/01/25 05:04
>>631
それかなりでかいライブラリだから気合入れて
調べないとわからなそう。おれも前から
試してみたいとは思ってたけど。。
http://www.cs.wustl.edu/~schmidt/ACE-overview.html

これだけの機能が必要になるケースじゃ
Javaでもつかった方がよさそうな感じかもね。

633 名前:HWND :02/01/25 05:37
ハンドルは16進数みたいだけど、ハンドルを文字列として
取得することは可能ですか?

634 名前:デフォルトの名無しさん :02/01/25 05:52
>>633
16進数と10進数の違いは?

635 名前:デフォルトの名無しさん :02/01/25 05:57
>>633
forとかで、if(Handoru==総当り)とかするしかないんじゃない?

636 名前:デフォルトの名無しさん :02/01/25 06:21
>>633
文字列って、どういう表現を期待してるんだ? ハンドルの値を取得したいなら
DWORD あたりにキャストして sprintf() で拾えるだろうし、その HWND に関連
付けられたウィンドウのタイトルなら GetWindowText() だろう。

っつか HWND の話なら、ここではなく VC++ スレに行きましょう。

637 名前:デフォルトの名無しさん :02/01/25 06:57
>>636
DWORD あたりにキャストして sprintf() では拾えない。
ハンドルを文字列で得るには総当りでしか無理だったはずです。

638 名前:HWND :02/01/25 07:19
>>635
総当たりじゃ使いものになりません。要するに無理なんですね。
ありがとうございました。

639 名前:デフォルトの名無しさん :02/01/25 07:28
ハンドルを文字列として取得するという意味がわからん


640 名前:デフォルトの名無しさん :02/01/25 08:07
ハァ?

641 名前:デフォルトの名無しさん :02/01/25 08:12
ウィンドウハンドルを指す文字列ったらHWNDをsprintfした奴だよな普通。
ていうかそれ以外ってなに?

642 名前:デフォルトの名無しさん :02/01/25 08:28
>>633=638はネタ|アフォとして、
おれは>>637の考えを聞きたい。

643 名前:デフォルトの名無しさん :02/01/25 09:09
(゚д゚) ハァ?

644 名前:デフォルトの名無しさん :02/01/25 11:39
次逝ってみよう次

645 名前:デフォルトの名無しさん :02/01/25 12:55
>>642
同意。総当たりって何を総当たり? 謎だ。

646 名前:教えて君 :02/01/26 01:59
カンマで区切られたデータ「TN-620,192,168,1,100」(初期値で与えられる)から文字列を切り出して表示する
項目1:TN-620
項目2:192
項目3:168
項目4:1
項目5:100

言ってる事から何をすんのかもサパーリです。教えてください
ってな質問はここでいいのだろうか

647 名前:デフォルトの名無しさん :02/01/26 07:56
わたしもサパーリです。

648 名前:デフォルトの名無しさん :02/01/26 11:12
>>646
で、私たちは何をすればいいんでしょうか。
サパーリです。#宿題なら宿題スレに行ってね。

649 名前:デフォルトの名無しさん :02/01/26 13:59
ミギャアアアアアア!
C++!
C++!
ミギャアアアアアアアアアア!!

650 名前:デフォルトの名無しさん :02/01/26 16:50
教えて欲しいのですが、
二つのクラスがお互いを使っているとき、コンパイルできないのです。

-------- ファイル ClassA.h --------
#ifndef CLASSA_WAS_INCLUDED
#define CLASSA_WAS_INCLUDED
#include "ClassB.h"
class ClassA{
 public:
  ClassB* getClassB();
};
#endif

-------- ファイル ClassB.h --------
#ifndef CLASSB_WAS_INCLUDED
#define CLASSB_WAS_INCLUDED
#include "ClassA.h"
class ClassB{
 public:
  ClassA* getClassA();
};

#endif

こんな場合です。お互い相手の名前が出てきた所でコンパイルエラーです。
こういう時はどうしたらいいのでしょうか?
ちなみに使っているコンパイラは Borland C++ 5.5 です。
(が、できれば汎用的なお返事をいただけるとうれしいです。)
よろしくお願いいたします。

651 名前::02/01/26 17:13
>650
ClassCでも作れよ(w

652 名前:デフォルトの名無しさん :02/01/26 17:26
>>>650
前方宣言

653 名前:650 :02/01/26 17:44
>>652
クラスにも前方参照って必要なんですね。
C を弄っていた頃はちゃんと(関数の宣言を)書いていたんですが、
最近すっかり Java に慣れてしまったもので忘れていました。
ありがとうございました。

参照
http://black.sakura.ne.jp/~third/cpp23.html

654 名前:デフォルトの名無しさん :02/01/27 07:34
std::stringstream のEOFの場所を手前にずらしたいときはどうすればいいですか?
つまり、
std::string s("0123456789");
s.erase(1);
をstringstreamでやりたいのです。

655 名前:デフォルトの名無しさん :02/01/27 07:55
ss.str(ss.str().erase(1));
はどうですか?効率は?

656 名前:デフォルトの名無しさん :02/01/27 23:19
やっとvirtualの使い方がわかった気がした…
C++が楽しくなった瞬間だった(w

657 名前:デフォルトの名無しさん :02/01/28 08:53
template<class T> class c
{
private:
static T s;
};

template<class T> T c<T>::s;

の最後の行ってなにをしてるのですか?
vc6の標準ライブラリの iosfwd の class fpos のところにあったのですが。

658 名前:デフォルトの名無しさん :02/01/28 09:01
staticメンバの定義

659 名前:デフォルトの名無しさん :02/01/28 09:23
掘って掘って
ようやく一番下まで掘り進んだとおもったら
さらにその下に巨大な地下帝国があった。


660 名前:デフォルトの名無しさん :02/01/28 09:32
>>658
static T s;
だけではダメナンデスカ?

661 名前:デフォルトの名無しさん :02/01/28 09:37
テンプレートをつかっておろうが

662 名前:デフォルトの名無しさん :02/01/28 09:45
template<class T> class c
{
//private:
public:
static T s;
};

//template<class T> T c<T>::s;

main() {
int i = c<int>::s;
char ch = c<char>::s
}

でコンパイルもリンクもできたのですが、なにかまずい状況が
あるのですか?



663 名前:661 :02/01/28 09:53
すいませんごめんなさいリンクできてませんでしたテンプレートはあくまで
テンプレートで実体を持っていないので宣言がいるということでしょうかでは逝きます

664 名前:662=663 :02/01/28 09:54
すいませんごめんなさい名前をまちがえました

665 名前:デフォルトの名無しさん :02/01/28 09:56
sに代入できたか?
sの値を表示できたか?

666 名前:デフォルトの名無しさん :02/01/28 09:56
おそかった
すまぬ

667 名前:デフォルトの名無しさん :02/01/28 13:20
Effective STL 訳本発売 age

668 名前:デフォルトの名無しさん :02/01/28 13:31
くそっ

669 名前: :02/01/28 17:36
>668
ん?洋書買ったばっかとかそーゆーコト?

670 名前:デフォルトの名無しさん :02/01/28 20:00
またよまなきゃいけない本がふえちった。
金ねーっつーの

671 名前:デフォルトの名無しさん :02/01/29 19:48
すいません、ちょっと質問。
メンバー関数として、「関数ポインタ」を返す関数ってどうやって定義したら
いいのでしょうか?

672 名前:デフォルトの名無しさん :02/01/29 20:04
>>671
別の型にキャストしてから渡しちゃう
とか、
構造体に入れて渡しちゃう
とか。

673 名前:デフォルトの名無しさん :02/01/29 23:05
class A{
 (void(*)()) f();
};
こんな感じ?ちなみに「メンバー関数ポインタ」を返す関数のことなら
(void(A::*)()) f();
って感じ。

674 名前:デフォルトの名無しさん :02/01/30 23:22
デストラクタでは例外を投げないよう気を付けませう。

675 名前:デフォルトの名無しさん :02/01/31 02:57
ある一定の期間内だけ有効になる変数の扱いってどうしてますか?
class Class{
int a;
int b;
void A( int _a, int _b ){ a = _a; b = _b; B(); C()}
void B(){ if (a==b) ...; }
void C(){ ...; }
};

↑のa,bみたいな場合。
この例のようにメンバ変数にすると、その変数が有効じゃないときにアクセスしてしまう可能性がありますよね。
BやCの引数に渡してやればOKですけど、数が多くなると問題ですよね。
a,bを格納するインナークラスを作ってそれを引数にして渡してやれば数が多くても大丈夫ですが、
ある一定期間だけのためにクラスを新設するのはなんだかもったいない(謎)気がします。

インナークラスを作るのが一番スマートな気がしますが・・・皆さんはどうでしょう?

676 名前:デフォルトの名無しさん :02/01/31 02:58
age忘れた

677 名前:デフォルトの名無しさん :02/01/31 09:13
>>675
>その変数が有効じゃないときにアクセス

どういう意味? コンストラクタで初期化してないとか? それにしては
インナークラス云々がわかんないんだけど。

678 名前:デフォルトの名無しさん :02/01/31 09:25
>変数が有効じゃないときにアクセスしてしまう可能性がありますよね。
あるのか(w

まああんまり使わないなら比較的長い名前にしておけば?

679 名前: :02/01/31 12:58
>675
漏れもそれ意味分かんない

680 名前:675 :02/01/31 14:24
>>677

> どういう意味? コンストラクタで初期化してないとか?

コンストラクトされた時点では値が不明なときです。
MFCのCDCなどのm_hDCのような物です(ただしもっと一時的です。Perlで言うlocalな変数です)。
m_hDCはどこから参照するかわかりませんからメンバ変数にしてありますが、それを使用するところでは必ずその値をチェックしなければいけません。

で、実際にはそういう変数がまとめて5個くらいあって、
それを使用する関数、というか使用してもよい関数が10個くらいです。
それらの関数すべてにその引数を渡すのは効率的じゃないです。

一つのクラス(構造体といったほうが伝わりやすい?)にまとめて、そのオブジェクトのアドレスを渡すようにするべきかな?

結局トレードオフの問題で、私が決めるべきことですが、皆さんはこういうときどうしているのでしょうか?
あるいはもっとスマートな方法があるのでしょうか。

> >変数が有効じゃないときにアクセスしてしまう可能性がありますよね。
> あるのか(w

一人で使う分にはないです。

681 名前:デフォルトの名無しさん :02/01/31 17:00
>>680
>それを使用するところでは必ずその値をチェックしなければいけません。

ならその変数をメンバ変数に持つかその変数から継承したクラスを作って
そのクラスのオブジェクトにアクセスするときはそのクラスが公開してる
インターフェイスでアクセスするようにすれば。で、そのインターフェイ
スは内部で値のチェックをやってると。要するにラッパ。
つーか例をもっと詳しくしてくれ。
>MFCのCDCなどのm_hDCのような物です(ただしもっと一時的です。Perlで言うlocalな変数です)。
も意味不明だ。

682 名前:675 :02/01/31 17:51
>>681

特定の関数内からしかアクセスできない変数を考えています。
(↑=特定の関数どうしで変数を共有したい、とも言い換えられます。)
コンパイル時に、できればそれ以外の関数内でその変数を参照していたらはじきたいので、メンバ変数というのはちょっと使いたくありません。

> >MFCのCDCなどのm_hDCのような物です(ただしもっと一時的です。Perlで言うlocalな変数です)。
> も意味不明だ。

Perlのlocal変数はわれながらいいたとえだと思ったのに。(;´Д`)

ま、いいや、やっぱりインナークラス作ることにします。
もし私の説明が解読できてしかももっといい方法を知ってる人がいたらよろしくお願いします。

683 名前:デフォルトの名無しさん :02/01/31 18:02
>>682
> Perlのlocal変数はわれながらいいたとえだと思ったのに。(;´Д`)
もしかして動的変数スコープを使いたいって話? それは C++ では無理だ。

知らない人のために補足しておくと、Perl5 はデフォルトで変数は全てグローバル、my
で宣言するとブロック内有効な静的スコープを持ち、local 宣言すると動的スコープを
持つようになります。(local 宣言したときに値を保存しておいて、スコープを抜けるときに
値を復元する)

684 名前:デフォルトの名無しさん :02/02/01 01:43
> 特定の関数内からしかアクセスできない変数を考えています。
> (↑=特定の関数どうしで変数を共有したい、とも言い換えられます。)

>ま、いいや、やっぱりインナークラス作ることにします。
の関係がよくわからんが、その変数を何かのクラスでくるんで、
関数を friend にしてやれば?



685 名前:デフォルトの名無しさん :02/02/01 01:54
>>683
次のコードで、my と local の違いが分かるね。

$x = 1;
foo();
print $x,"\n";

sub foo() {
# my($x)
local($x);
$x = 2;
print $x,",";
bar();
}
sub bar() {
print $x,",";
}

結果は、local のときが 2,2,1 で、my のときが 2,1,1, になります。



686 名前:681 :02/02/01 05:23
>>682
>特定の関数内からしかアクセスできない変数を考えています。
>(↑=特定の関数どうしで変数を共有したい、とも言い換えられます。)

それを文字通りに「特定の関数内からしかアクセスできないメモリ =
クラスオブジェクトのprivate宣言されたメンバデータ」
って回答しかない。コンパイル時に弾くにはこれしかないね。
で、それをクラス間にまたがって行うには>>684の言うように
friendしかないと。

>Perlのlocal変数はわれながらいいたとえだと思ったのに。(;´Д`)

Perlのlocalがグローバルシンボルテーブルを一時的に上書きするのと
C++で「特定の関数で値を共有する」というのとでは意味も前提もまる
っきり違う。グローバルな特殊変数に基づいた振る舞いをするサブルー
チンの振る舞いを変更したいときにlocal宣言で特殊変数を一時上書きして
やったりするが、そういうシンボルベースの動的な振る舞いとMFCがラップ
したm_hDCのようなvolatile(システムによって非同期に変更される)な変数
の扱いとは全く別で、だから意味不明と書いた。
C++で同じシンボルで振る舞いを変更するには、参照の参照先を付け替える
かメソッドをオーバーライドするかしかない。

687 名前:デフォルトの名無しさん :02/02/01 05:42
More Exceptinal C++読み終わりましたが
絶対買いだとは言えないかも。
例外についてはMoreなしの方で言い終わっていた的な。
文字列クラスの実装の話の方が多いし。

688 名前:デフォルトの名無しさん :02/02/01 06:28
継承していないクラスのコンストラクタにおいて
class XXX{
public:
  XXX():yyy(),zzz(){
    return;
}
このような表記があるのですが、
これって何をしているのでしょうか?
自分の理解では親クラスのコンストラクタに
パラメータを渡していると思っていたのですが、
どうも違うみたいです。よく分かりません。
教えてください。

689 名前:デフォルトの名無しさん :02/02/01 06:51
>>688
メンバ変数の初期化デス。

690 名前:デフォルトの名無しさん :02/02/01 07:02
>>689
こういった書き方も出来るんですね。
初めて知りました。どうもです。

691 名前:デフォルトの名無しさん :02/02/01 08:12
>>689
一つ思ったんですが、
どうしてこんな書き方が必要なんですか?
クラスのコンストラクタにおいて、
渡されたメンバ変数を使って初期化すれば
いいだけの話に思えるのですが。
もし問題となるケースがあるとするならば
コンストラクタの実行順序ですが、
これだけが上のような表記が必要な理由ですか?

692 名前:デフォルトの名無しさん :02/02/01 08:13
×:渡されたメンバ変数を使って初期化
○:渡されたパラメータを使ってメンバ変数を初期化

693 名前:デフォルトの名無しさん :02/02/01 08:32
メンバがconstだったりリファレンスだったり
する場合の初期化

694 名前:デフォルトの名無しさん :02/02/01 09:16
>>693
今見ているソースではconstでもリファレンスでも
ないのに先のような表記になってます。
これは勘違いということになるんでしょうかね?
private:
 ZZZ zzz;
 YYY yyy;
こんなかんじです。意味無しですか?

695 名前:デフォルトの名無しさん :02/02/01 09:21
>>691
> コンストラクタの実行順序
これは初期化リストの書き方によらず、常にメンバ変数の定義順になる。

696 名前:デフォルトの名無しさん :02/02/01 09:27
殺気から色々と教えてくれてありがとうございます。
>>695
メンバの初期化の順序は処理系依存ではなく言語仕様なんですね。
よーく頭に叩き込んでおきます。

697 名前:デフォルトの名無しさん :02/02/01 09:29
>>694

コンストラクタをポインタなどを介さずに直接呼び出すにはその記法が唯一な気がするのだが

たとえば

class hoge {
std::vector<int> vi;
public:
hoge(int n): vi(n) {}
//...
};

とか.

そうしないと

hoge(int n) { vi.resize(n); }

とかにするしかないような.

698 名前:デフォルトの名無しさん :02/02/01 09:37
うぉー、ありがとうございます!!
もう>>697さん大好き!惚れました!!(´ε`)チュッ

確かにそうですね。上のような感じだと、
パラメータを渡してメンバ変数を初期化するには
そのような書き方しかないですね。
resizeに相当するようなメソッドがないクラスは
その方法しかありません。勘違いしてました。

699 名前:デフォルトの名無しさん :02/02/01 09:38
>>697
そもそも、デフォルトコンストラクタを持たないクラスの場合には、書かないと
コンパイル通らないしね。

700 名前:デフォルトの名無しさん :02/02/01 11:15
>>698

もっとも,この場合には

hoge(int n) { vi = std::vector<int>(n); }

とできるけどね.

結局,初期化と代入とを区別するための記法だね.


701 名前:デフォルトの名無しさん :02/02/01 14:40
それだとコンストラクタが2回と代入演算子が使われるのでは?

702 名前:デフォルトの名無しさん :02/02/01 14:51
でも例えばコンストラクタ用の例外構文をコンパイラがサポートしてない場合とかは
このように書くしかないと思う

703 名前:675 :02/02/01 15:29
>>684

使用する関数が継承等で増える可能性もあるのでfriend指定は出来ません。
関数をオーバーライドするときにクラスも新しく派生させればいいですけれど。

>>686

m_hDCとlocalが同じとは書いていません。

m_hDCの値はオブジェクトが作成されて破壊または分離されるまでの間でのみ有効ですよね。
(オブジェクトが生成される前に、生成に成功したかどうかをm_hDCの値から判断する処理をしても無意味です。)
有効範囲という意味で、m_hDCのような値が常に有効とは限らない変数。

しかしm_hDCほど寿命は長くなく、もっと一時的に、ある関数が呼ばれている間のみ、意味を持つ変数はみなさんどうするかなぁと。
Perlのlocal変数と同じようなことはメンバ変数を使った最初のやり方で出来ています。
しかしPerlのlocal変数同様特定の関数からのみ呼ばれることを期待して書いたとき、ほかの場所から呼ばれた場合に問題がでます。

で、それへの対応策が必要な変数をすべて引数へ渡すこと、さらにそれをクラスにまとめることです。
こうすればどこから呼ばれても、引数さえちゃんと渡されていれば問題なく動きます。
メンバ変数の無駄遣いもなくなりますが、クラスが1つ増えます。


704 名前:683 :02/02/01 15:44
>>703
> m_hDCとlocalが同じとは書いていません。
書き方が悪すぎ、に一票。

705 名前:にゃお :02/02/01 16:24
Windows 9x において現在接続されている HDD / CD-ROM / IDE コントローラ
などのハードウェア名情報はどのように取得すればよいのでしょうか?
レジストリエディタで検索してみると当然みつかりますが、環境によって場所が違うようです。


706 名前: :02/02/01 16:41
>705
そーゆープラットフォーム依存の話は他当たった方が良いと思われ

707 名前:にゃお :02/02/01 16:46
>706
ごっ、ごめんなさい。どーもスレチガイだったようで・・・
Windowsプログラムの話題をやってるところに投稿するべきですね。


708 名前:デフォルトの名無しさん :02/02/01 21:45
g++2.95用のリンカでコンパイルした
ライブラリはg++3.03でリンクすることは
できないのでしょうか?

709 名前:デフォルトの名無しさん :02/02/01 22:03
VD++6.0でClistBoxを使っているのですが、
リストを選択した状態でエンターを押した時に
エディットボックスに、選択状態のリストの文字列を送ってやりたいのですが、
リストの項目番号を取得することもエンターを検出することも出来ません。

どうやったらいいのでしょうか?




710 名前:デフォルトの名無しさん :02/02/01 22:05
>>708-709
処理系のスレへどうぞ

711 名前:デフォルトの名無しさん :02/02/02 01:07
>>703
……ようやくあなたの言っている意味が分かった。しかし、
「書き方が悪すぎ」に、もう一票だな。
で、あらためて >>675 に戻るが、コンパイル時にチェックしたいなら、
引数で渡すしかない。実行時の assert によるチェックでよいなら、
変数をポインタにするという手はある。ふだんは NULL のままだけど、
関数 A() の中で有効なポインタを設定する。
それよりも設計を見直して、変数a, b と関数 B(), C() だけをまとめた
クラスを考えたほうがよいと思う。


712 名前:デフォルトの名無しさん :02/02/02 17:27
ハンドルされていない例外があります。
stack overflowとか出るんですけど、どうしたらいいですか?

713 名前:デフォルトの名無しさん :02/02/02 17:30
節約しなさい、スタック。

714 名前:デフォルトの名無しさん :02/02/02 17:32
C++って、全ての基底クラス?っていうのかな
MFCでいうところのCObjectクラスってのがないよね。
あれって何でなの?
そういうものだって言われて終わりかな…。


715 名前:デフォルトの名無しさん :02/02/02 17:36
スタックって何ですか?どうしたら節約できるんですか?

716 名前:デフォルトの名無しさん :02/02/02 17:36
そういうものだ。

717 名前:デフォルトの名無しさん :02/02/02 17:44
>>715
> どうしたら節約できるんですか?

でかいauto変数を使わないようにする。
少しは自分で調べろよ。


718 名前:デフォルトの名無しさん :02/02/02 18:32
>>715
「おいオメー さっきから うるせえぞ
『知りません』『知りません』ってよォーーーー
『知りません』・・・そんな言葉は使う必要がねーんだ
なぜなら オレやオレたちの仲間は その言葉を頭に浮かべた時には!
既にGoogleや書籍で調べがついちまって もうすでに『知っている』からだッ!
だから 使った事がねェーーーッ
『知っている』なら 使ってもいいッ!」


719 名前:ithink :02/02/02 20:07
>714
基底クラスがあるとすると例えば多重継承をどう処理する?などなど

720 名前:デフォルトの名無しさん :02/02/02 21:39
>>714
そんなもん要らんから。

721 名前:デフォルトの名無しさん :02/02/02 22:24
>>714
MFCがこまるから。

722 名前:デフォルトの名無しさん :02/02/02 23:10
>>715
再帰で無限ループとかになってないか?

723 名前:デフォルトの名無しさん :02/02/03 15:43
'a'ってint型じゃないのですか?
プログラミング言語C++に
void print(int);
void print(char);
があった場合、print('a');とするとprint(char)が
呼ばれるって書いてあるんですけど。

724 名前:デフォルトの名無しさん :02/02/03 15:58
>>723
C だと int, C++ だと char

725 名前:デフォルトの名無しさん :02/02/03 17:48
こういうときはポインタでわたす
こういうときはリファレンスでわたす
とか決めてる?

726 名前:デフォルトの名無しさん :02/02/03 18:05
>>725
場合によって相手を変える場合にはポインタ
初期設定したら二度と相手を変えない場合には参照

NULL がくる可能性があるならポインタ
NULL がきたらまずい場合は参照

もちろん

 foo(int& n);

 int *p = NULL;
 foo(*p);

とか書けばコンパイラのエラーチェックに引っかからないが、そりゃ NULL ポインタ
をデリファレンスしたヤツが悪い。

727 名前:デフォルトの名無しさん :02/02/03 21:30
ポインタの場合は、メンバ変数とかグローバル変数とかに保持されて、その関数を抜けた後も使われる場合があるけど、
参照で渡す場合はそれをしないという自分ルール。

参照にNULL渡す奴なんぞ知らんってことついては >>726 に同意。

728 名前:デフォルトの名無しさん :02/02/03 22:36
privateとpublic書く順番。

class A{
private:
 int a;
public:
 void f();
};

class A{
public:
 void f();
private:
 int a;
};

今までずっとprivateを先に書いてたけど、STLのソースなんかは逆なのね・・・どっちが普通??

729 名前: :02/02/03 22:59
>728
漏れはヘッダ見た時にインターフェースが見やすいように
public が先

730 名前:デフォルトの名無しさん :02/02/03 23:39
>>728漏れは
public:クラス名・タイプ宣言
public:コンストラクタ
public:メソッド
public:フィールド
public:クラス
protected:クラス名・タイプ宣言
 :
 :
private:クラス名・タイプ宣言
 :
 :

731 名前:デフォルトの名無しさん :02/02/03 23:41
>>729
おれは private 書かずに、いきなりメンバ変数書くので private が先。

たいてい、メンバ変数は pImpl だけだったり。

732 名前:デフォルトの名無しさん :02/02/04 09:19
C++で追加された演算子(?)に
  const_cast dynamic_cast reinterpret_cast static_cast
がありますよね?
これがいまいちわからんのです。
普通のキャストと何が違うんでしょうか?
C++を勉強した本には載ってなかったし、BCBのヘルプを見ても使用例がなくてどうも。。
有用な使用例サンプルを出していただけると泣けるほど嬉しいです。

733 名前:デフォルトの名無しさん :02/02/04 09:22
>>732
http://www.s34.co.jp/cpptechdoc/article/newcast/

734 名前:デフォルトの名無しさん :02/02/04 10:02
>>732
>C++を勉強した本

どんな本で勉強してるんだよ...

735 名前:デフォルトの名無しさん :02/02/04 11:04
>>733
すばらしい。そこみたら即効で理解できてしまいました。
いいとこ教えてもらった〜。ありがとー。

>>734
「CプログラマのためのC++入門」です。
ネームスペースやテンプレートもなかったです。
まだ定まってないようでした。

736 名前:デフォルトの名無しさん :02/02/04 11:14
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄」
―――――――――――――‐┬┘
                        | 
       ____.____    | 
     |        |        |   | 
     |        | ∧_∧ |   | 
     |        |( ´∀`)つ ミ | 古くさい本は投げ捨てろ
     |        |/ ⊃  ノ |   |  □
        ̄ ̄ ̄ ̄' ̄ ̄ ̄ ̄    |

737 名前:デフォルトの名無しさん :02/02/04 11:29
燃やして暖をとろう

738 名前:デフォルトの名無しさん :02/02/04 14:43
質問です。
A[0]=1,A[1]=2,A[2]=3
B[0]=4,B[1]=5,B[2]=6,B[3]=7
上記のデータを
vector<vector<int> > IntAry;
で用意して以下の様に格納したいのですが
IntAry[0][0]=1
IntAry[0][1]=2
IntAry[0][2]=3

IntAry[1][0]=4
IntAry[1][1]=5
IntAry[1][2]=6
IntAry[1][3]=7

一発で*Aから*IntAry[0]にコピーする方法がどうも出来ません。
なにか良い方法ありましたらご教授お願いします。

739 名前:デフォルトの名無しさん :02/02/04 14:47
>>735
>「CプログラマのためのC++入門」

Cプログラマ向けの本らしいのにCと違うキャストの種類すら載って
ないとは恐ろしい度胸だね。
classとstructの違いくらいしか載ってないのかね。
入門向けC++本といえば、ろくにSTLと標準ライブラリについて書いてない
のが沢山ありそうだ。Cの本でprintfについて書いてないというのもあまり
ないだろうに。そういうものがSTLの周知を妨げているのかもしれん。

740 名前:739 :02/02/04 14:51
std::copy(A, A + 2, IntAry[0].begin());
std::copy(B, B + 3, IntAry[1].begin());
一発ってコレの繰り返しじゃ駄目なの?

741 名前:740 :02/02/04 14:51
>>738ね。

742 名前:デフォルトの名無しさん :02/02/04 15:49
>>739
まぁ、参考文献が『The Programming Language C++ second edition』だったりするからな。
つか、謝辞の日付1992年4月だぞ。古すぎてやめといたほうがいい部類の本かもな。

743 名前:デフォルトの名無しさん :02/02/04 15:51
>>740
ありがとうございます。今検証中なのですが
std::copy(IntAry[0], IntAry[0].begin() + 2, C[0]);
逆に書き戻す場合上記ではないのでしょうか。
といいつつエラーが出るのでまずはgoogleしてきます。

744 名前: :02/02/04 15:58
>743
vector の vector の中身は直列な一つのメモリにはならんぞ

745 名前:744 :02/02/04 15:59
スマソ,勘違いしたっぽい

std::copy(IntAry[0].begin(), IntAry[0].end(), C[0]);

で良いっつー話かな?


746 名前:744 :02/02/04 16:01
さらにスマソ
std::copy(IntAry[0].begin(), IntAry[0].end(), &C[0]);
だな.
これなら C が配列でも vector でもOK


747 名前:ワェス・パラヤ :02/02/04 17:49
「みんな嫌いだぁ!メモリリーク起きちゃえ〜」

#include <iostream.h>
int main()
{
for(int i=0;i < 1000;i++)
int *p=new int;
return 0;
}

748 名前:デフォルトの名無しさん :02/02/04 17:58
>>746
出来ました。ありがとうございます。
今度は自分がBYTE配列、相手(C)がLPVOIDの場合に上手く行く様に
頑張ってます。これは同じ様にやれば特に問題なしかな??

749 名前:(l)←マムコ :02/02/04 18:01
>>747
while(1){

}

↑じゃないの?

750 名前:デフォルトの名無しさん :02/02/04 18:07
>>747
E-mail欄のコメント書き忘れんなよ


■過去ログ置き場に戻る■ 1- 前250 次250 最新50
DAT2HTML 0.33f Converted.