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


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

C++相談室
751 名前:741 :2001/06/27(水) 21:44
BC++落としてコンパイルしたら、
  table.push_back(new Func0());
でwarningがでた。(動くけど)

警告 W8030 test_fobj.cc 15: 'x' パラメータ(vector<Foo::FuncT *,allocator<Foo::F
uncT *> >::push_back(Foo::FuncT * const &))のために一時変数を使用する(関数 Foo:
:Foo() )

体言止めで言われてもわからない‥
ポインタの参照にnewしたのを直接渡しちゃダメなのかな?
やっぱりC++難しい。鬱だ。

752 名前:sage :2001/06/27(水) 22:12
>>751
原則:
参照渡しするためには、対象となるオブジェクトがアドレスを持っていなければならない。

つまり、ポインタの参照渡しには、どこかのメモリ空間上にポインタ変数が置かれていなければ
ならない。

OK?

753 名前:741 :2001/06/27(水) 22:40
>>752
わかりました〜。ありがとうございます〜。

754 名前:691@C++わかってない :2001/06/27(水) 23:15
>>701 (>>745)
あー、メソッドのポインタを取得してコールするという話で、
どうしてハッシュ(というかmap)が出てくるんだよぉー
と、お察しの通りそこに目がいって早とちりしてしまいました。すんまソ。

>>741 (>>744)
なるほど、それが関数オブジェクトっていう事ですか。いいですねー。
それで実装する場合は、どういう感じになるか、
operator()とかは不慣れなだからfuncにして、
ほぐして、改造してみました(delete無いままだけど)

// コンパイラはg++
#include <vector>
#include <iostream>
class FuncT {
public:
  virtual void func(void) = 0;
  int bar; // メンバを全てのFunc?::func()で共有したかった
  FuncT() {
    bar = 0;
  }
};
// >>746のいう通り↓これを30個書くのはめんどくさい
class Func0: public FuncT {
public:
  void func(void);
};
class Func1: public FuncT {
public:
  void func(void);
};
class Foo {
  vector<FuncT*> table;
public:
  Foo() {
    table.push_back(new Func0());
    table.push_back(new Func1());
  };
  void dispatch(int no) {
    FuncT* f = table[no];
    f->func();
  };
};
// ここより上はヘッダということで
void Func0::func(void) {
  cout << "Func0:" << bar << endl;
  bar++;
}
void Func1::func(void) {
  cout << "Func1:" << bar << endl;
  bar++;
}
main() {
  Foo foo;
  foo.dispatch(0); //=> Func0:0
  foo.dispatch(1); //=> Func1:0 ←barは共有されてない
}

755 名前:691@C++わかってない :2001/06/27(水) 23:16
上の続き

一状態、一オブジェクトは拡張性があっていいとは思ったけど
そもそもfunc0とfunc1はメンバ(実体)を共有する必要があったんですよ。
上のソースだと独立したオブジェクトになってるので、
メンバが共有されないの当然ですね。

んで、今回、自分のやっているのは関数オブジェクトも魅力的だけど
>>747のいう通り>>736の方法を使うのが適しているように思いました

756 名前:デフォルトの名無しさん :2001/06/27(水) 23:20
ここ上下関係がはっきりしてて読みやすいです。
へんなアオリもないし、的確な突っ込みは入るしw
みなさんありがとう

757 名前:701 :2001/06/27(水) 23:38
>>755
あう?
共有する実体ってのが変数の事なら、関数オブジェクトに
その変数持ってるインスタンスを引数でわたせばよいじゃん。

758 名前:デフォルトの名無しさん :2001/06/27(水) 23:40
>>751-753
何が分かったというのだろう。
newの戻り値のポインタが一時オブジェクトとして作成され、
それのconst参照がpush_backに渡される。
つまり警告は冗長であり、そのコードは完全に正しい。

759 名前:デフォルトの名無しさん :2001/06/27(水) 23:56
>>758
一時オブジェクトなら、vectorが破棄されたときに、
その一時オブジェクトも破棄されるんじゃない?
もしこれを記述した人が、永続的に存在して
deleteされないオブジェクトを作ったつもりでコードを書いたなら、
期待通りの動作をしないよね。
だからwarningが出ないと危険だし、
errorにしてもいいくらいだと思うぞ。

760 名前:691@C++わかってない :2001/06/27(水) 23:57
>>757
それもいい方法なんだけど、void func0(Foo *_this) という風になって、
C++化したおかげで_thisを葬れるというメリットがなくなってしまうヨ。

761 名前:SdC :2001/06/28(木) 00:08
【delete のエラー?】
 VC++ のコンソールモードでプログラミングをしています。
クラス内において、new で動的に生成した配列を、デストラクタにおいて delete [] で解放しようとしたら、デバッグ窓に、
 Heap block at 00342808 modified at 00342A80 past requested size of 270
みたいな文が表示されて停止してしまいます。(コンパイル後の実行ファイルに対するデバッグのような画面になります。)
このエラーの意味自体もよくわからないのですが、どこがいけないのでしょうか?

762 名前:デフォルトの名無しさん :2001/06/28(木) 00:16
>Heap block at 00342808 modified at 00342A80 past requested size of 270

00342808番地に確保されたヒープブロックにおいて、
確保したサイズ"270"を超えたところにある、
00342A80番地が変更されてしまっています。

const int size = 270;
int *p = new int[size];
p[size+1] = 10;
delete []p;

763 名前:762 :2001/06/28(木) 00:19
ていうかさ、エラーメッセージを読む気が無いなら、
プログラムしないで下さい。
そのほうが人に迷惑をかけずに人生をまっとうできます。

764 名前:デフォルトの名無しさん :2001/06/28(木) 00:29
>>760
this渡しは隠蔽されているだけで、実際には行われているよ
メリットでも何でもないよ。

765 名前:デフォルトの名無しさん :2001/06/28(木) 00:37
>>760
ポインタ一個引数に渡すのに、何かデメリットがあるの?

766 名前:691@C++わかってない :2001/06/28(木) 00:39
>>764
葬れるというのは言い方がおかしかった。隠蔽ということですね

767 名前:デフォルトの名無しさん :2001/06/28(木) 00:47
>>765
見た目的な美しさ以外には、特にデメリットは無いだろうな。
でも確かになんか違和感がある。

だけどさ、やっぱ根本的に問題があるでしょう。
このお題そのものに。
C++の制限の多くは、機能的な不備よりも、
下手な設計を排除するためにわざと制限していることが
ほとんどだと思うのだけどどうよ。

768 名前:デフォルトの名無しさん :2001/06/28(木) 00:48
>>759
一時的で、破棄されてしまうのは、ポインタオブジェクト(妙な言い方)
そのものであって、newで確保した「ポインタの指し示す先」ではない。

void test()
{ char *tmp = new char; }
という関数があったとして、tmpは破棄されるけど、
newで確保した領域はそのまま残るだろ。

ちなみに、 >>749のリークってのは、Foo::~Fooで、
tableにあるFuncT解放していない、って事。

769 名前:sage :2001/06/28(木) 00:54
>>766
thisを不用意に晒さないですむという意味かな。
ちょこっとだけ気持ちを理解した。

でも、C++は、きれいに書くためのプログラミング言語じゃないと思う。

どうしてもというなら、
Cから引き継いだプリプロセッサ機能や
関数オブジェクトを書いて
汚いと思えるところを隠蔽すればいい。

自己満足にならない程度に、きれいに書こうね。

770 名前:デフォルトの名無しさん :2001/06/28(木) 00:59
>>769
うむ、そうだ。ひさびさに激しく同意。

771 名前:701 :2001/06/28(木) 01:02
Func1::func(Foo* foo){
foo->setHage(foo->getBaka()+foo->getTimpo());
foo->funcHoge(foo->getTimpo());
}

とかやる(汚すぎな例だね(藁))のは、Visitorパターンとか
いうデザインパターンの適用例といって良いんじゃない?
これって汚いロジックなのかなあ?

772 名前:sage :2001/06/28(木) 01:10
(゜д゜)<friend関数はだいたいきちゃない

773 名前:741 :2001/06/28(木) 01:21
>>758
const参照の時は、初期化するものが左辺値でないと、
一時オブジェクトが作成されるんですね。
んで、一時オブジェクトは参照がつくられたスコープの間
存在するので、それがリークする事はないと

>>752は、一般的な(constでない)参照の初期化の時に
は正しいと

C++こわいよ〜

774 名前:デフォルトの名無しさん :2001/06/28(木) 01:29
>>758
オブジェクトは生成されるけど、ポインタ自身はアドレス空間上に置かれてないってことだろ。
コンパイラが親切に一時オブジェクトを作ってくれてるだけだ。

775 名前:SdC(761) :2001/06/28(木) 01:31
>>762
ありがとうございました。解放する配列とは別の配列のインデックスが上限を越えていました。
これからはきちんと英文エラーメッセージも反芻して精進します、ご迷惑をおかけいたしました。

776 名前:デフォルトの名無しさん :2001/06/28(木) 01:31
>>773
ここで作られた一時オブジェクトは、つまり、ポインタのことだ。
一時的に作られたポインタは、参照渡しが終わって関数から戻ってくるとメモリ上から消える。

newで確保したオブジェクトは、deleteで明示的に消さない限り残るので
この場合リークするよ。

しっかり勉強しろ

777 名前:デフォルトの名無しさん :2001/06/28(木) 01:35
>>759
悲劇的だ。的はずれで何を言ってよいか私には分からず、
彼は自分があらゆる質問に答える権利を有していないことを宣言したに等しい。
一時オブジェクトの分からない貴方はあと20分ほど本を読む必要がある。

このキャラに限界を感じている私は、貴方に本気でへこまないでほしい
と言うことしかできない。

778 名前:デフォルトの名無しさん :2001/06/28(木) 01:41
>>774
ポインタの一時オブジェクトが作成され静かにアドレス空間に置かれる。
>コンパイラが親切に一時オブジェクトを作ってくれてるだけだ。
もう私は書くペンを持っていない。
このコンパイラがたまたま親切にも一時オブジェクトを作ってくれている
とでも言いたいのだろうか。

779 名前:デフォルトの名無しさん :2001/06/28(木) 01:47
>>777-778
おもろい

780 名前:741 :2001/06/28(木) 01:48
>>776
deleteしないとリークするのはわかってるよん。
実害無いから放っておいただけ

前半は理解しました。ありがとうございます。

781 名前:>>769 :2001/06/28(木) 03:01
この場合メンバ関数へのポインタを使うのが綺麗だと思うのだが。
T* _this を渡して、操作はもろもろ protected なり public なり
にする、なんてのはどー考えても変だぞ...

(たとえば PPP なんかを実装する場合を考えてみてくれ)

782 名前:デフォルトの名無しさん :2001/06/28(木) 03:23
これってやっちゃダメ?

delete this;

当然だけどデストラクタをprivateなんかに放り込んで
newでしかclass生成できないようにしてだけど。
あと、newの配列を使えないようにしとかないとダメか。

783 名前:デフォルトの名無しさん :2001/06/28(木) 20:30
>>782
使いかたを間違えなければ可
COMのQueryInterface::Releaseの実装でも使われとります。
delete後にクラスのメンバをいぢったりしてはいけない。

784 名前:デフォルトの名無しさん :2001/06/28(木) 20:37
C++でのnamespaceの扱い方の定石をご教授願います。

例えばstlを使おうとした場合に
入門書なんかだと
例1:
#include <memory>
using namespace std:
int main(int argc, char* argv[])
{
  auto_ptr<Hoge> AutoHoge(new Hoge);
}

見たいな感じになっていますが・・・

自分はつい最近までstlの専門書(つーかC++の専門書)をあまり読んだことがなかったのです。
今までは我流でこんな感じにやっていました。
例2:
#include <memory>
int main(int argc, char* argv[])
{
  std::auto_ptr<Hoge> AutoHoge(new Hoge);
}

namespaceをせっかく使ってるんだからこのやり方のほうが
名前空間を汚さなくていいんじゃないかと思っているんですが・・・

せめて
例3:
#include <memory>
int main(int argc, char* argv[])
{
  using std::auto_ptr;
  auto_ptr<Hoge> AutoHoge(new Hoge);
}

の方がいいと思うんですが・・・

よかったらそれぞれのメリット・デメリットを踏まえて定石をご教授ねがいます。

785 名前:デフォルトの名無しさん :2001/06/28(木) 23:17
age

786 名前:デフォルトの名無しさん :2001/06/28(木) 23:26
C++6.0ってなんですか?
http://www.geocities.co.jp/SiliconValley-Cupertino/2788/

787 名前:デフォルトの名無しさん :2001/06/29(金) 00:26
>>784
あなたの主張はもっともだと思います。
必ずしも書籍が正しいとは限りません。

タイプ量が増えるのがイヤな人と、
名前空間以前のコンパイラをサポートするためのものだと考えるのが
妥当だと思います< using namespace

788 名前:デフォルトの名無しさん :2001/06/29(金) 00:52
書籍はコードを簡略化するためにやってるだけだろ。

789 名前: :2001/06/29(金) 16:02
using namespace デフォルトの名無しさん;

790 名前:すみません。。 :2001/06/29(金) 16:19
スミマセン、これってなんで bbb と表示されるんでしょうか...?

bool flag;

flag=true;

if(flag==true) cout << aaa << endl;
else cout << bbb << endl;

まったく謎なんです、、。どなたかわかりましたら教えて下さい(;´Д`)

791 名前:790 :2001/06/29(金) 16:21
しかもデバッガでflagの値を見ると
'・'
なんです、、。

792 名前:名無しさん :2001/06/29(金) 16:54
>>790
gccだと稀にメソッド内でメンバー変数にちゃんと代入できない
バグのあるバージョンがあるみたいだけど。
egcs-2.9xという表示の出る奴。
変数をpublicにして外から代入すると直る。

793 名前:790 :2001/06/29(金) 17:00
>>792さん
public で直りました!
本当にありがとうございます!

794 名前:名無しさん :2001/06/29(金) 17:03
>>793
こういう対処は悲しいね。
良いバージョンが出回ることを望みます。

795 名前:782 :2001/06/29(金) 21:11
>>783
ありがとうございます。
のど元に引っかかってた骨が取れました。

796 名前:「partial」の意味について :2001/06/30(土) 00:35
1.Class template partial specializations
クラステンプレート部分特別バージョン

2.Partial ordering of class template specializations
クラステンプレート特別バージョンの部分順位付け

3.Partial ordering of function templates
関数テンプレートの部分順位付け

1.の「部分」は、「部分的に」テンプレート引数が
特定されているということですが、
2.と3.の「部分」は、数学用語らしい「部分順位」
のことだと考えています。
だから、2.をより詳しく書けば、
Partial ordering of class template partial specializations
クラステンプレート部分特別バージョンの部分順位付け
と書けると思います。
これは正しいでしょうか?

797 名前:shige :2001/06/30(土) 01:42
  ハハハ
  ∧_∧  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 ( ^∀^)<  あほか
 ( つ ⊂ ) \_________
  .)  ) )
 (__)_)     (^∀^)ゲラゲラ


ruby >>>>>>>>>>>>>>>>>>>>>>> C++

798 名前:デフォルトの名無しさん :2001/06/30(土) 08:03
>>797
あんたきしょいよ。

799 名前:デフォルトの名無しさん :2001/06/30(土) 15:07
ruby しかできない人なのか...

800 名前:デフォルトの名無しさん :2001/06/30(土) 19:16
printfで%pでのアドレス表示は、coutではどうやったらいいんですか。

801 名前:デフォルトの名無しさん :2001/06/30(土) 19:36
int *p;
cout << p

802 名前:デフォルトの名無しさん :2001/06/30(土) 19:37
%p表示と同じ書式で出したいというならしらーん

あれはコンパイラの作りに依存するからね

803 名前:デフォルトの名無しさん :2001/06/30(土) 19:49
>>800
int *p;
cout << (int)p
ってのはだめか?

804 名前:デフォルトの名無しさん :2001/06/30(土) 20:13
>>803
16bitの頃のx86でHugeModelだったとして、それ書いて逝ってよし

805 名前:デフォルトの名無しさん :2001/07/01(日) 03:12
sprintf最強ってことでいいですか

806 名前:デフォルトの名無しさん :2001/07/01(日) 03:33
_snprintfの方がもっとずっと、いろんな意味でよいのだが
標準でないので逝ってくる。

ベンダの提供するcoutの出力で我慢できない?

807 名前:とうちゃん :2001/07/02(月) 00:30
クラスの相互参照ってどうすればよし?
たとえば

class A{
B b;
....
}

class B{
A a;
....
}
ってエラーがでるんですが、、、

808 名前:デフォルトの名無しさん :2001/07/02(月) 00:33
>>807
class B;
class A{
B b;
....
}

class B{
A a;
....
}
ってやってみ?

809 名前:デフォルトの名無しさん :2001/07/02(月) 00:34
class B;
class A{B b;};
class B{A a;};

内部メソッドを呼びだすインライン関数はclass定義中には書けないよね?>ALL

810 名前:デフォルトの名無しさん :2001/07/02(月) 00:37
>>809
その内部メソッドが既に定義されてればできる.

811 名前:809 :2001/07/02(月) 00:38
>>810
言葉足りずスマヌ、もちろん相互参照等で定義されていない場合。

812 名前:デフォルトの名無しさん :2001/07/02(月) 00:53
はーい質問。

C++でインスタンス化されていないクラスのメソッドを呼びだす方法について質問です。
どこぞで3つある、と聞いたのですが、

1:static void fuction(..)
全然問題ないですね。

2:reinterpret_cast<A*>((void*)0).function();
大抵のコンパイラなら問題なさそうですね〜。
もちろんfunctionの中でメンバ変数にアクセスしてたら死亡です。

3:???
俺にはこの程度しか思いつかなかったんですが、他にありますか?

813 名前:デフォルトの名無しさん :2001/07/02(月) 00:57
>>812
そういう状況に陥ったことないのだが、
なんでそんなことするんだ?

814 名前:812 :2001/07/02(月) 00:59
>>813
意味はありません。ただ3つもあるのか?と思っただけで。
もちろんstaticにするのが当たり前です

815 名前:デフォルトの名無しさん :2001/07/02(月) 01:05
>>814
俺が無知なへぼプログラマかと思っちゃったよ。
ただのへぼでよかったんだ。

わーい

816 名前:デフォルトの名無しさん :2001/07/02(月) 01:07
>>815
俺はへぼでいいから答え教えろやゴルァ

817 名前:とうちゃん :2001/07/02(月) 01:07
>>808
その方法でやってみたんですが
うまくいかなくて、、、
#include <stdio.h>
class B;

class A{
private:
int value;
B *b;
public:
A(void);
int get(void);
int get_b(void);
};
A::A(void)
{
value = 0;
}
int A::get(void)
{
return(value);
}
int A::get_b(void)
{
return(b->get());
}

class B{
private:
int value;
A *a;
public:
B(void);
int get(void);
int get_a(void);
};
B::B(void)
{
value = 100;
}
int B::get(void)
{
return(value);
}
int B::get_a(void)
{
return(a->get());
}

なかんじです

818 名前:デフォルトの名無しさん :2001/07/02(月) 01:08
>>816
へぼだからわからんよゴルァ

819 名前:デフォルトの名無しさん :2001/07/02(月) 01:09
Aの関数定義をBの宣言の後に持っていくべし

820 名前:デフォルトの名無しさん :2001/07/02(月) 01:12
>>817
定義されて無い関数は呼べません。
定義されていないクラスは使えません。

821 名前:Java使いなのでC++ようわからん :2001/07/02(月) 01:12
これはできないのかな?

static void Hoge::hage(){}

Hoge* hoge = NULL;
hoge->hage();

どうせHoge::hage()で呼べるんだから、
全く意味がないと思われるが…どうでしょうか。

822 名前:デフォルトの名無しさん :2001/07/02(月) 01:13
出来るけど、それが解答だとするとちょっと残念だな。
とにかくtnx>821

823 名前:デフォルトの名無しさん :2001/07/02(月) 01:15
>>821
借りの実体を与えてやれば呼べるって奴でしょ。
それ2番と同じだよ。
そして、これも又同じ。
A &a = *(A*)NULL;
a.function();

824 名前:Java使いなのでC++ようわからん :2001/07/02(月) 01:21
じゃあ、関数ポインタ直呼び?これはできるの?

(*func)() = Hoge::hage();

func();

みたいな?これはC++じゃないと思われるが。

825 名前:とうちゃん :2001/07/02(月) 01:23
>>820
てことは>>821-823
みたいにやらないと相互参照はできないってことですか?
(といっても なにしてるかよくわkらん、、、
勉強しなおそう!)

826 名前:デフォルトの名無しさん :2001/07/02(月) 01:25
>>825
ちがうちがう、あれはまた別の話(^^;

#include <stdio.h>
class B;

class A{
private:
int value;
B *b;
public:
A(void);
int get(void);
int get_b(void);
};

class B{
private:
int value;
A *a;
public:
B(void);
int get(void);
int get_a(void);
};

A::A(void)
{
value = 0;
}
int A::get(void)
{
return(value);
}
int A::get_b(void)
{
return(b->get());
}

B::B(void)
{
value = 100;
}

int B::get(void)
{
return(value);
}

int B::get_a(void)
{
return(a->get());
}

827 名前:デフォルトの名無しさん :2001/07/02(月) 01:27
>>825
自分の人の良さにあきれるが…答えてやろう。
本来この程度のことは試行錯誤して解答を探し出すもんだが。

class B;
class A{B b;public:B* get_b();};
class B{A a;public:A* get_a();};
void A::get_b(){return &b;}
void B::get_a(){return &a;}

これを参考にしてみそ

828 名前:とうちゃん :2001/07/02(月) 01:33
>>826
クラスの定義を先にもってくればいいんですか。
ありがとうございます。
でもクラス定義を別々のヘッダーでする場合はどうすれば?
、、、とこれはもっともっと勉強してから
いつかしたいと重います

>>827
(中途半端に勉強した)CからC++へ移って
こまりはてています。がんばって勉強しますかな
どうもです。

829 名前:デフォルトの名無しさん :2001/07/02(月) 01:44
//file1
class B;
class A{B b;public:B* get_b();};

// file2
class A;
class B{A a;public:A* get_a();};

//file3-4
void A::get_b(){return &b;}
void B::get_a(){return &a;}

だろ

830 名前:RIP_MAPIRO :2001/07/02(月) 09:08
//Sample.h
#if !defined(Sample_H__uuid__INCLUDED_)
#define Sample_H__uuid__INCLUDED_
class A;
class B;

class A
{
/*
メンバ変数定義、
メンバ函数宣言
*/
};

class B
{
/*
メンバ変数定義、
メンバ函数宣言
*/
};
#endif


//Sample.cpp
#include "Sample.h"
/*
メンバ函数定義(実装)
static メンバ変数初期化
*/


//Reference.cpp
#include "Sample.h"
//class A,B を使って実装

831 名前:機知guy :2001/07/02(月) 15:37
age

832 名前:とうちゃん :2001/07/02(月) 20:56
せっかくおしえていただいたのに・・・
できねっす・・・

833 名前:デフォルトの名無しさん :2001/07/02(月) 21:24
試行錯誤ねえ
エバると有難がられる、か...

834 名前:初心者 :2001/07/02(月) 23:30
C++BuilderでPaintのプログラムを打ってるんですが、
Imageコンポーネントって具体的に言って、どういう働きをして
どういうことができるんですか?
あと、ビットマップとはなんですか?

835 名前:00 :2001/07/03(火) 12:14
kokoyori yasasii sure ha naissuka?

836 名前:デフォルトの名無しさん :2001/07/03(火) 12:35
>>835
優しいか易しいかどっちやねん。

837 名前:デフォルトの名無しさん :2001/07/04(水) 03:53
どうしてもあるデータに対して、それを管理するクラスと参照するだけの
クラスに分けたものを作りたく思い次のようにやってみました。

class A{
  Data data;
public:
  const Data* getData(){ return &data; }
};

class B{
  const Data* pRefData;
public:
  B( const Data* d ) : pRefData( d ){}
};

main(){
  A a;
  B b( a.getData() );
}

friendにするまでもない、ということで上記のようにしてみましたが
やはりあまり誉められたやり方ではありません。
このことをもう少し綺麗に行う方法ってないでしょうか?

838 名前:デフォルトの名無しさん :2001/07/04(水) 03:59
>>837
やりたきゃやってもいいけど設計間違え気味。

見るだけクラスを元クラスから派生、もしくはその逆にしなさい

839 名前:デフォルトの名無しさん :2001/07/04(水) 21:38
>>837
"UML" "関連クラス" で検索してみな?

840 名前:837 :2001/07/04(水) 23:33
>>838
両クラスの役割が違うこともあって考えもしませんでした。確かにそうですねぇ。
>>839
dataを分離して関連クラスにしてしまうわけですか。こっちもいいなぁ。

どちらでいくか迷いますが、悩みが高尚なものになって嬉しいです。
お二人ともありがとうございました。

841 名前:デフォルトの名無しさん :2001/07/04(水) 23:37
GoF読み始めたらクラス設計つまんなくなって来ちゃったよ。
俺の車輪は世界一ィィィ

842 名前:デフォルトの名無しさん :2001/07/06(金) 03:37
age

843 名前:デフォルトの名無しさん :2001/07/06(金) 12:05
なぜ thread関数は、staticメンバにしないとだめなんでしょうか?

844 名前:デフォルトの名無しさん :2001/07/06(金) 12:52
>>843
thread 関数に this を渡せないから。(Microsoft Visual C++ の実装の場合)

845 名前:843 :2001/07/06(金) 13:41
>>844さんの
ヒントでthisを渡せない理由を調べてみました。
どうやら関数呼び出し規約に秘密が隠されていそうです。
__stdcall、__cdeclの違いがビンゴのようです。
thiscallは__cdeclと同じ仕様でスタックにthisが積まれ、
非staticメンバ関数の呼び出し規約であるということなので、
__stdcallで呼び出されるthread関数はstaticにしなければならない
ということなのですね。

846 名前:名無しサン :2001/07/06(金) 13:49
つーかソレ以前に最適化の結果渡らなくなったり
バージョンアップで実装が変化したりするするから
Cの関数にthis渡すなってこともある。
どうしてもメッセージパッシングしたければCOMだけど
C++とCにはオーバースペックだなぁ。

847 名前:844 :2001/07/06(金) 13:53
>>845
いや、違うよ。

__thiscall は __stdcall とよく似てるが、
ecx で this が渡される点が違うのよ。
すなわち、VC++ の実装では this はスタックには積まれない。

仮に引数のないメンバ関数(実質 __cdecl と同じ)があったとしても、
やっぱり this を渡せないことには変わりがないので、
thread 関数は非スタティックなメンバ関数を呼び出せない。

848 名前:843 :2001/07/06(金) 18:33
>>847
度々ありがとうございます。
呼び出し規約を誤って理解するところでした。

何故スレッドが__stdcallでなければならないのか?
という疑問も有りましたが、スタックのクリアを自分自身で
行うということなので、スレッドの終了時に都合がよさそうだ
と納得しました。

849 名前:デフォルトの名無しさん :2001/07/06(金) 21:11
>>848
OS の API が C++ を前提にしてないから、だよ。
例えば EPOC などの C++ に特化した OS だと、Thread も
C++ のオブジェクトを使ってナニソレする。

850 名前:3B :2001/07/06(金) 21:14
>>841
シュトロハイム?

851 名前:ど素人 :2001/07/07(土) 23:00
C++のStringクラスの実装ってどうなってるんでしょうか?

852 名前:デフォルトの名無しさん :2001/07/07(土) 23:15
ソース読め>851

853 名前:デフォルトの名無しさん :2001/07/07(土) 23:27
言語実装や最適化以前の問題として、
OSが要求するのは割り込み「関数」だから、だろう。
割り込み「メソッド」じゃないので、
(やりかたの如何を問わず)thisポインタをやり取り
する手段(Interface)が用意されてないというだけのこと。

>>849
ん?興味あり。EPOCとやらではどういう感じになってるんですか?
VCやDelやJavaみたいに内部実装のthreadに一対一対応
するThreadクラスがあって、そいつのインスタンスのrunメソッド
とかがOSによって動かされる、みたいなスタイルっすか?

まとめ:
非Object用であるthreadをObject用に翻訳する機能を
MFCなりVCLなりJVM(?)なりが持っている、ってわけだなー。

854 名前:デフォルトの名無しさん :2001/07/08(日) 01:04
C++前提のOSってBeOSがたしかそうだと聞いたことがある。
いつだかの互換性のないバージョンアップのときに
大変なことになったらしい。

需要がなけりゃ問題にもならんけどね。

855 名前:デフォルトの名無しさん :2001/07/08(日) 03:11
去年の今ごろBoland C++compilerなんかを何も分からずにインストールして
放置していた者です。
それから1年が起ちましたがCドライブが圧迫されてきてファイルを削除しなければ
ならない状況に追いこまれ、ファイルのデカイC++を消そうと思った次第です。
が、アンインストールの方法がかいていないのでとても困っております。
どなたか教え手下さい。

856 名前:デフォルトの名無しさん :2001/07/08(日) 03:42
素直にディレクトリごと消せば良し

857 名前:デフォルトの名無しさん :2001/07/08(日) 03:46
>>852
あんなデッカイプログラムをディレクトリごと消去ですか?
レジストリに膨大なファイルが残る気がするのですが。
信じていいのですか?

858 名前:デフォルトの名無しさん :2001/07/08(日) 04:50
レジストリにファイルが残るという表現が謎…

859 名前:デフォルトの名無しさん :2001/07/08(日) 08:06
>>857
レジストリのどこを使っているのですか?
C++ビルダーが大量に使っているのは知っているのですが・・
BCCが、どこを使っているのか、わかりません・・

860 名前:デフォルトの名無しさん :2001/07/08(日) 08:08
>>857
レジストリは、あなたの気分で残るわけでもなければ、
もとファイルがでかいかどうかで残るわけでもないです。
「書け」と命じられたから書かれる(そして残る)んです。
それだけのことでしょ?

861 名前:851 :2001/07/08(日) 09:11
恥ずかしながら
ソースの見方がわかりません...

862 名前:843 :2001/07/08(日) 12:14
849,853,854
OSとAPIの都合が真相のようですね。
この2、3日勉強して理解が更に深まった感じです。
今思うとVC++スレに質問する内容であった気がします。
レスありがとうございました。

863 名前:デフォルトの名無しさん :2001/07/08(日) 14:38
アンインストーラーがレジストリをきれいにしてくれるなんて
ただの妄想。

864 名前:デフォルトの名無しさん :2001/07/08(日) 15:01
c++では
printfツカワナイホウガイイノデスカ・・・?

865 名前:sage :2001/07/08(日) 15:13
Windowsならファイルの検索でクラス名を指定して探しなさい。
ソースファイルをインストールしてないだけなら、
CDかWEBから探してきてインストールしなさい。

ソースを公開していないようなコンパイラを使用しているなら
あきらめなさい。

866 名前:sage :2001/07/08(日) 15:15
>>864
使ってもいいよ。

867 名前:デフォルトの名無しさん :2001/07/08(日) 23:44
いまいちcoutが使いにくいのは気のせいですか。

868 名前:sage :2001/07/08(日) 23:51
俺もそう思う

869 名前:sage :2001/07/09(月) 00:51
>>868
さんくす だってcoutつかいにくいもん
printfになれてるからなぁ

>>867
あちきもそうおもいます

>>868
仲間がいいぱい

870 名前:デフォルトの名無しさん :2001/07/09(月) 00:51
・・・さげまちがえた・・・

871 名前:美加 :2001/07/09(月) 22:45
c++を始めたばかりなんですが、
単語を覚えるのに
void→ボイド  int→イント  include→インクルード
という風に、頭ではカタカナにして覚えると覚えやすんですけど、
cin
とか、読めないものがあるんですよね。(シーアイエヌと覚えている)
どこか、カタカナ表記されているホームページとかってありませんか?
 

872 名前:実験君 :2001/07/09(月) 22:54
class AAA
{
public:
AAA(int i);
operator int();

private:
AAA(const AAA&);
};

AAA getAAA();

int main(int argc, char* argv[])
{
AAA a(getAAA());

return 0;
}

これコンパイル通ります?

873 名前:デフォルトの名無しさん :2001/07/09(月) 23:13
>>872
何がやりたいのか分からん

874 名前:sage :2001/07/09(月) 23:14
getAAA()って何処の星にあるのよ。

875 名前:872 :2001/07/09(月) 23:31
aの初期設定の時に、getAAAの戻り値に対して
ユーザ定義変換operator int()が使用されるのか知りたい。
VC++では通らないのだが
おそらくC++標準では通るのではないかと。

ちなみに
A a((int)getAAA());
ならもちろん通る。

876 名前:デフォルトの名無しさん :2001/07/09(月) 23:33
で、それ使って何やるの?
使わないほうがいいような・・・

877 名前:872 :2001/07/09(月) 23:39
auto_ptrの実装を見てこの問題に直面した。
話せば長い。

878 名前:sage :2001/07/09(月) 23:54
試してないけど
operator int () cosnt にしたらどうなる?

879 名前:872 :2001/07/09(月) 23:57
>>878
うちでは特に変わらずやはり通らないなあ

880 名前:sage :2001/07/10(火) 00:06
調べずに書いてすまぬ。

privateなAAA(const AAA&)がじゃまをするね。

#include <stdio.h>

class AAA
{
public:
AAA(int i) {}
operator int() { }

private:
// AAA(const AAA&);
};

AAA getAAA() { AAA aaa(1); return aaa; }

int main(int argc, char* argv[])
{
AAA a(getAAA());

return 0;
}

ここまでしかできんかったよ。

881 名前:デフォルトの名無しさん :2001/07/10(火) 00:10
>>880
そういうことだと、それはデフォルトのコピー
コンストラクタ呼んでるだけになるんじゃない
のでしょうか?

882 名前:sage :2001/07/10(火) 00:14
operator int()が暗黙的に呼ばれて
AAA(int i)が次に呼ばれるんだと思う。


ところで、privateのコンストラクタを消すのは反則なの?

883 名前:872 :2001/07/10(火) 00:16
>>880-881
そう。デフォルトコピーコンストラクタの使用は禁止して
operator int()とAAA(int i)を使わせたい。
これがC++標準で可なのか知りたい。
不可なわけはないと思うのだがARM12.3.1に微妙な記述がある。

884 名前:872 :2001/07/10(火) 00:19
>>882
消したらoperator int()は呼ばれない。

885 名前:sage :2001/07/10(火) 00:29
その通りだ。
退却する。

886 名前:872 :2001/07/10(火) 10:11
アクセス権の違いによって多重定義が解決されることはない
のでコンパイラは正しかった。
というわけで以下がまさに知りたいことだったのですが

class AAA
{
public:
AAA(AAA&) { } // const をなくす
AAA(int i) { }
operator int() { }
};

AAA getAAA() { return AAA(1); }

int main(int argc, char* argv[])
{
AAA a(getAAA());

return 0;
}

getAAA();の返す一時オブジェクトに対してAAA(AAA&);(constでない)は呼べないので
operator int()が呼ばれるはずだが、VC++では呼ばれません。
(というより一時オブジェクトはさっくり削除されてAAA(int i)だけが呼ばれる。)
他のコンパイラではどうでしょうか。

887 名前:デフォルトの名無しさん :2001/07/10(火) 22:44
これじゃ駄目なの?

AAA a(static_cast<int>(getAAA()));

888 名前:887 :2001/07/10(火) 22:46
あ、getAAAはインライン関数じゃないものとして。

889 名前:デフォルトの名無しさん :2001/07/11(水) 01:01
VC++とBC++5.5ではどっちのほうがANSIに近いのでしょうか?

890 名前:デフォルトの名無しさん :2001/07/11(水) 22:14
>>889
gccのほうが近いと思う

891 名前:デフォルトの名無しさん :2001/07/11(水) 23:04
Originatorをいろいろ派生させました。で、
内容をMementoに保存したいんですが、この場合
Mementoに渡すStateも派生させちゃったりして
いいものなんでしょうか。礼儀的に。

892 名前:デフォルトの名無しさん :2001/07/13(金) 22:07
g++でのコンパイル時に、汎用クラスのコンストラクタに関して"undifined reference"
って言われました。クラスの宣言部のみをヘッダファイルにして、実現部は別ファイルにあります。
これらを一つのファイルで実現するとうまくいきました。なんで? templateではないクラス
の場合はファイルを分割してもうまくいくのに。

893 名前:デフォルトの名無しさん :2001/07/13(金) 23:56
>>892
普通のクラスはコンパイル時に機械語を生成することを期待される.
template はインスタンス化しないと機械語を生成しないから、と予想.

894 名前:デフォルトの名無しさん :2001/07/14(土) 01:24
>>892
宣言間違ってるとかでは?
コピーペーストしてみ

895 名前:892 :2001/07/14(土) 01:32
>>893>
宣言部と実現部を別ファイルにした場合にうまくいかないというのはなぜですか?
分離させることで何が起こるんでしょう?
コンパイラに実現部のありかを知らせる方法でもあるんですか?

896 名前:デフォルトの名無しさん :2001/07/14(土) 02:23
あたま大じょぶ?>895
ふつーインライン展開と同じ理屈が適用されると思うんだけど。

897 名前:892 :2001/07/14(土) 02:33
>>892
普通のクラスは分離させてもOKで、テンプレートクラスはそのままではだめというのが、

>>893

の話だと思うし、その意味もなんとなくわかります。
がしかし、どうすればテンプレートクラスでも分割できるのかがわかりません。
すんません初心者なもので。

898 名前:デフォルトの名無しさん :2001/07/14(土) 02:35
#includeで依存関係ちゃんとやってる?>897

899 名前:892 :2001/07/14(土) 02:51
>>898
定義のみを記述したヘッダファイルを、実現部のあるファイルとクラスを利用する
メインのファイルとにincludeしています。2重に読みこまれないように、#ifndef
も使っています。

900 名前:名無しさん@Emacs :2001/07/14(土) 02:59
テンプレート(の実装の多く)はマクロと同じで、
実際使う時にソースコード本体が必要になる。
ので、分割コンパイルはできない。
どうしてもファイルをわけたかったら、
*.inl のようなファイルにわけて、
それを *.h のケツで #inlcude するとか、
コンパイル速度の向上には有効でない方法を取るのが良いかと。
保守性はまあ、あがるかも知れないし、あがらないかもしれない。

901 名前:デフォルトの名無しさん :2001/07/14(土) 03:07
インクリメンタルコンパイルをオプション指定すれば、
多少は向上しなかったっけ?>速度

902 名前:デフォルトの名無しさん :2001/07/14(土) 04:16
C 相談室 2
http://piza.2ch.net/test/read.cgi?bbs=tech&key=995051742

作りました。
■■■■■■■■■■■■■■■■■■■■■■■■■■
C 相談室 2
http://piza.2ch.net/test/read.cgi?bbs=tech&key=995051742

作りました。
■■■■■■■■■■■■■■■■■■■■■■■■■■
C 相談室 2
http://piza.2ch.net/test/read.cgi?bbs=tech&key=995051742

作りました。
■■■■■■■■■■■■■■■■■■■■■■■■■■

903 名前:デフォルトの名無しさん :2001/07/14(土) 07:15
悲惨な902のいるスレ

904 名前:デフォルトの名無しさん :2001/07/14(土) 16:25
関数と変数が入ってるクラスをwriteメソッドで保存したら、メンバ関数はどうやって保存されるのですか?

905 名前:sage :2001/07/14(土) 16:28
>>904
ふつうはインスタンスの持つデータしか保存しないので
メソッド自身は保存しません。

906 名前:デフォルトの名無しさん :2001/07/14(土) 16:45
なるほど。それは良いことを聞きました。どうもありがとうございました。

907 名前:デフォルトの名無しさん :2001/07/15(日) 13:09
>>904
シリアライズに関わる問題は気ぃ付けろよ。

908 名前:デフォルトの名無しさん :2001/07/15(日) 14:48
v(^・^)v

909 名前:906 :2001/07/15(日) 21:32
>907
シリアライズって、どんなことですか?
あと、スタテクライブラリを作ったあと、他のプロジェクトで使うときに、リンクにライブラリを加えた後ヘッダファイルをインクルードさせているのですが、もっと楽な方法ありませんか?

910 名前:デフォルトの名無しさん :2001/07/16(月) 00:52
>>909
シリアライズとは、オブジェクトの状態を保存しておくこと。
あとでロードしたり、通信で送ったりして、
オブジェクトの状態を復帰させるのが目的。

ライブラリ化でそれ以上楽な方法は無い。
強いて言えばライブラリ化せず、常にソースごとコピー。

911 名前:906 :2001/07/16(月) 19:28
わかりました。どうも有り難うございました。

912 名前:v :2001/07/20(金) 00:16
すみません、DLL内でクラス内部に

class DllExport me{
vector<int> a;
}

と宣言すると、'a' : class 'std::vector<int,class std::allocator<int> >' は __export キーワードを使って class 'me' にエクスポートしてください。
という警告文が出るのですが、何故ですか?


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