C++相談室 part23

このエントリーをはてなブックマークに追加
C++にeclipseのようにgetterとsetterを自動で書いてくれるツールはありませんか?
お勧めの物を教えて下さい。
>>761
マクロプログラミング
>>761
全データメンバに洩れなくgetter/setterがついてるコードでも書く気か?
情報隠蔽の理念と根本的に対立する思想だな
>>763
eclipseの場合は変数ごとにgetter,setterのチェックボックスのツリーが出てきて
自由にgetterとsetterを追加削除できるんです。
getterだけ追加してreadonlyにする事も簡単に出来ます
C++ではset/getなんてしないよ。
コンストラクタ以外のメンバは全て全部privateにして、
通信する相手は友達だけにする。

のは冗談としても、普通に構造体で直にアクセスさせることも
多い。set/getなんてまどろっこしいことはあまりやらない。
C++でPascalのようなbegin/endが使えるようになるツールはありませんか?
C++でAPLのように行列の計算が入出力込みで1行で書けるツールはありませんか?
C++でCOBOLのようにPERFORM THRUが使えるツールはありませんか?
C++でJavaのようにGCが使えるツールはありませんか?

てめえで作れつーの
>>765
C++をbetter Cとして使うのならそれでいいのかもしれませんが、
私はOOPLとしてC++を使っているので。
setterとgetterの利点についてはこの辺読んでください。
http://www.muraoka.info.waseda.ac.jp/~fukumori/oo/why_use_getters_and_setters_j.html

>>766
あなたは勘違いしてると思うんですが、setter,getterはJava特有の物ではありません。
OOPLならばどんな言語でもsetterとgetterは書くはずです。C++も無論そうです。
関係ありませんが、C++でGCが使えるライブラリは既に存在しますし私も利用しています。
ちょっと面倒だがそれくらい自分で書いたほうがいいかも。
ツール使う方がかえって面倒になることがある(例:VC++のメンバの追加ダイアログ)
YAGNI,YAGNI、と云いつつ、広域置換を使う俺。
>>761
ない
どうも無さそうですね。仕方ないんで自作して使います。
>>767
知ってるOOPLの範囲狭すぎ
>>772
propertyの存在も知っています。
結局propertyにしてもgetとsetはありますよね。
>>767
getter/setterが必須だと思うのなら手間を惜しむな。
#本来全く考えなしにgetter/setterを書くべきではない。そうであるなら大した手間ではないだろう。

どうしても手間を惜しみたいならeclipseで書け。
まさかeclipseではJavaしか開発できないなんて思っているわけじゃないだろ?
>>774
CDTにプロパティ自動生成があればeclipse使うんですが、
JDTにしか無いんですよね。リファクタリング機能にしてもプロパティ自動生成にしても。
>>773
…。

では、setter/getterなんて本来必要なくて、直接そのオブジェクト自身にIOまで行わせるべきだという主張の存在は?
(クラス構造が静的だと辛いけど、後付け可能なら無茶な話じゃ無い)
>>776
そもそも動的型付け以前に、
C++のようなプリミティブ型が存在する言語にそのような理想論を持ち込まれても困るんですが。
Java厨にはかまうな。放置しろ。
>>778
なんでそこでJava厨が出てくるのか貴方の頭の構造が全く理解不能です。
「OOPLとしてC++を使っている」、と、
「Javaの言語機能という制限上で培われた流儀のOOPをC++でも行おうとしている」、の微妙な違いというか
OOPLならば(>>767)って言うくらいだから
Java/C++/C#/ObjectPascal etcの「なんちゃってOO言語」じゃなく
SmalltalkとかEifellとかの純粋なOOPLの事を言ってるんだろうね。
こういう生物をJava厨って呼ぶのか。
783704@お勉強中:03/10/09 03:17
えー、本を読んでいるとメンバ変数はprivateに入れろと書かれていますが、
やっぱり時と場合によってpublicにする場合もあると言う議論でしょうか?

このレベルだと翻訳して貰わないと良く理解できません。
話しそれて申し訳ないけど、外からは使えないのに
記述的に公開しているprivateって概念は、
糞だと思うが仕方ないんだよな…
>>767
> http://www.muraoka.info.waseda.ac.jp/~fukumori/oo/why_use_getters_and_setters_j.html
は、「データメンバをpublicにせずに、代わりにgetter/setterを
使うことの利点」 だろ?「privateメンバには対応するgetter/setterを
設ける」 という習慣はやめた方がいい。

Why getter and setter methods are evil
 http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html
でも読んでこい。
>「privateメンバには対応するgetter/setterを設ける」
って誰が言ってるんだ?>>763
>>785 代りにどうしたらいいの?
>>784
pimpl知らないの?
>>770
すてき
>>786
761。
ツール=機械と読んだ。
自動=機械的に=人情は関係なしと読んだ。
privateはお前が言い出した妄想。
791デフォルトの名無しさん:03/10/10 21:46
以降の流れについて説明する「まとまった処理についてのコメント」と、
「ちょっとした補足コメント」を区別したいのですが、これ!という方法があったらぜひ教えてください。

■気分的にはこんな感じです
//まとまった処理についてのコメント{
 //ちょっとした補足コメント
 //ちょっとした補足コメント


■↓だと「「ちょっとした補足コメント」の方が、スペースや位置的書きづらくて…

  //これから、まとまった処理が始まるよ

  int hoge = 7; //hogeについての、ちょっとした補足だよ

■↓だと、両者の区別がいまいちしづらくて…

  //これから、まとまった処理が始まるよ

  //hogeについての、ちょっとした補足だよ
  int hoge = 7;
/////////////////////////////////////////////////////////////
//まとまった処理についてのコメント
/////////////////////////////////////////////////////////////
hage::hage()
{

//hogeについての、ちょっとした補足だよ
int hoge = 7;






}
793791:03/10/10 21:58
>>792
にゃるほど!ちょっと大人しめにしてマクロ登録しますた
レス感謝!ありがとうございやした
794791:03/10/10 22:00
いやまてよ、「まとまった処理は関数にしろや」というアイロニーも
込められてるっぽいな。お気遣いありがとう。
/**
* まとまった処理についてのコメント
* @param
* @return
*/
796デフォルトの名無しさん:03/10/10 23:30
>>784
つかう場面がわからない君がクソだと思うぞ
>>796
誤爆?
>>797
正爆
799デフォルトの名無しさん:03/10/11 10:50
最近ようやく入門書を読み終えて関数やクラスの使い方が
わかってきた初心者ですが、質問させてください。

入門書やWeb上に文字列を扱うクラスなどはよく載ってるんですが、
それ以外に、自分のしたい事が実現できるクラスはみなさんどーやって
探してるんでしょうか?ネット上を徘徊したり本を読み漁って、
偶然そのクラスが使われているサンプルを見つけるんでしょうか・・・?
そうだとしても、最初に使った人はどーやって使い方を覚えたのか気になります。
C++のクラス一覧みたいなものがどこかにあったら教えてください。
>>799
意味分からんw

クラスライブラリのリンク集ならこのスレの始めに
あるぞ。使い方とか、最低限ドキュメントに目を通してから
言えよ。
>>799
無いクラスは作るものだ。
>>799
使い方というか、アルゴリズムの解説してる本なら沢山ある。
アルゴリズムの解説を読んで、クラスは自分で書く。

あと、有名なアルゴリズムなら大体誰かがコード化してる。
問題は大半が英語なのと、C言語(非OOP)で書かれてる事が多いこと。

C++ のクラス一覧は MSDN でも嫁。
>>802
>C言語(非OOP)
洩れの知る限りCで書かれたライブラリの多くは充分にOOPだが何か?
C++で書かれたMFCなんぞよりもずっとマシだったりする
>>803
ああ、まあ、ライブラリと呼べるようなまともな奴は確かに OOP してるし、
MFC の方がよっぽど糞だけど。

逆に俺は C で OOP してるソース見ると、
素直に C++ 使えよというやるせない気持ちになる。
805デフォルトの名無しさん:03/10/11 14:09
char *buf=new char[100];
などという感じで確保したメモリを解放するときは、
delete buf; と delete[] buf; のどちらを使えばいいのでしょうか。
とりあえずコンパイルはどちらも通るんですが。
入門書を穴が開くほど読め。
話はそれからだ。
>>805
これを試して見るべし。分からなければmyallocは気にしなくて良い。
#include <iostream>

struct myalloc_type{} myalloc;
void *operator new(size_t size, myalloc_type)
{
&nbap;&nbap;&nbap;&nbap;std::cout << "new\n";
&nbap;&nbap;&nbap;&nbap;return ::operator new(size);
}
void *operator new[](size_t size, myalloc_type)
{
&nbap;&nbap;&nbap;&nbap;std::cout << "new[]\n";
&nbap;&nbap;&nbap;&nbap;return ::operator new[](size);
}
int main()
{
&nbap;&nbap;&nbap;&nbap;char *buf = new(myalloc) char[100];
}
>>806
配列サイズが定数のときの挙動までは書いていない入門書もあると思われ。
808807:03/10/11 14:24
ミスった。もう一回
#include <iostream>

struct myalloc_type{} myalloc;
void *operator new(size_t size, myalloc_type)
{
    std::cout << "new\n";
    return ::operator new(size);
}
void *operator new[](size_t size, myalloc_type)
{
    std::cout << "new[]\n";
    return ::operator new[](size);
}
int main()
{
    char *buf = new(myalloc) char[100];
}
>>805
delete[]
>>807
定数かどうかがどう関係あるんだろうか。
811デフォルトの名無しさん:03/10/11 15:00
実行時にバンドルなんたらって出るエラーは、
どういうとき出るエラーか、誰か教えてくだされ。
newで配列を確保する場合、もしそれがクラスオブジェクトの配列ならば、
delete[]とdeleteのどちらでも、配列の要素すべてが解放される。
違いは、delete[]の場合全要素に対してデストラクタが呼ばれるのに対し、
deleteでは先頭要素のみデストラクタが呼ばれるということである。

と教科書に書いてあってびっくり。今まで知らなかった。
まさか、未定義だろ
各処理系でどうかは知ったことでないが
>>812
VC++だけ。
>>312
そんな教科書捨てろ
どこに嘘が書いてあるかわかったもんじゃない
C++の教科書は禿本かPrimerしかないと思ってるけど。
変に読者にこびったような本はダメぽ。
禿本って何?禿く分かるC++?(謎
818B.S:03/10/12 00:30
禿々言うな。
お前等だって将来禿るかも知れないんだぞ?
うるせー禿
既につるっつるに剃りあげてますが何か?
まだあるのに自ら剃るなんてなんて罰当たりな
いやらしい程のM禿で、見るにみかねて、、、スレ違いスマソ
>>816
確かにあの二冊は読者に優しくないよな。
分厚くて重くて大きくて・・・・
>>823
私は禿本を風呂の中に持ち込んで読みましたが何か?
本は湯船につかってゆっくり読む習慣なので。
>>824
ああなるほど。水に浮かべれば浮力で重さが気にならなくなると。
>>823
私はあの本を見ながらオナニ○しましたがナニか?
「ハァハァ・・・・・vector
 ハァハァ・・・・・string
 ハァハァ・・・・・いてれーたぁー。」
と、このように。
最近VC++触りだした、浦島太郎ですが。
VCでの最初のスタートは下記のようですが。
_tMain(....)
_tWinMain(....)

昔は  main()   WinMain()  だったはず。
どういった理由や意味で変わったのでしょう?
「_t」て、なに?
いろいろサーチしたけど、見つからなかったのでお願いします。
>>827
UNICODEに対応させるため
質問させて下さい。VC6.0です。

#include <iostream>
#include <iterator>
#include <sstream>
#include <conio.h>

void main()
{
std::wostringstream ss;
std::ostream_iterator<wchar_t, wchar_t> it(ss, L",");
*(it++) = L'A';
*(it++) = L'B';
*(it++) = L'C';
std::wcout << ss.str() << std::endl;
getch();
}

A,B,C, と表示されるのを期待してるんですけど、
wchar_tがshortとして扱われる為
65,66,67, と表示されてしまいます。
どうしたらいいんでしょう?
>828 さんありがとうございます。
確かに昔は内部コードはSJISだったかな、(うろ覚え
「_t」でソース内の日本語文字列がUNICODEになって
オブジェクトになると考えていいですか?
>>629
wchar_tを正しくサポートするコンパイラを使う。
>>831
いい加減、VC++6ってのはもうダメだろ。金ないなら
.NETSDKにcl.exeついてくるんだからそれでもつかえと。
cygwinでもいいけどさ。
833829:03/10/12 21:42
>>831-832
なるほど、VC6のせいでしたか。
boost::regex使ってて出た問題だったんですが、
これじゃ他の部分もまともに動いてるかどうか、わからないですね。
どうもありがとうございました。
>>830自己レス。
main
_tmain     (Win32
_tWinMain   (MFC
でやってみたけど、EXEをHEXダンプで見たら、3つともSJISで
文字列入ってた、謎だ。
多分どこかが、UNICODEなんだろう、きっと・・・・・
何処なんだろうと、聞いてみる?^^;
WinMain(HINSTANCE, HINSTANCE, char*, int);
wWinMain(HINSTANCE, HINSTANCE, wchar_t*, int);
>>834
828がUNICODEに対応させるとは書いたが、UNICODEになるとは誰も書いてない。
コンパイルオプション
>>833-837さんいろいろありがとう。
いろいろやって見て、一応の理解ができました。
ちなみに、>>829のソースはVC++.NET2003ではA,B,Cと出ます。
みなさんありがとーー
>>834
そんなのどうでもいいから早くUnicodeでコンパイルする方法を調べろ
>>829
std::locale::global(std::locale("japanese"));
IDEとしてのVC6にはなんの不満もないので、cl.exeだけ差し替えて、
(バッチ使って別にコンパイルとかではなく)、そのまま使えないかなぁ…。

などと>>832見ながら思った秋の夜長…。
>IDEとしてのVC6
class宣言がマクロ化されてるとアウトなのはちょっと勘弁してほしい
templateインスタンス型のメンバを保守できないとわかったときはズッコケた
ncbdj状態も頻度高杉
>>841
.NETSDKのcl.exeとPSDKとVC++6を組み合わせて使ってます。
特に問題ないです。
.NET SDK の cl.exe は最適化できないとか言ううわさを聞いた気がするんだけど
その辺りどうなの?
>>845
できないといわれてるけど、/G[3-7]オプションはとおるよ。
versionは13.10.3077
/G[3-7]は単体で意味あんの?
/O[1-2]と組み合わせないと意味無いんじゃないの?
>>847
Uni厨で済みませんでした。無知で恥かしいです。
$cl.exe /G6 /O2 test.c
Microsoft(R) 32-bit C/C++ Standard Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

cl : コマンド ライン warning D4029 : 標準の編集コンパイラでは最適化は使用できません。
test.c
Microsoft (R) Incremental Linker Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.

/out:test.exe
つーかgccでも単体で-march=i686なんてやらないで-O2とか-O3と組み合わせて使うよね。
RDBで複数の項目にインデックスを貼って高速に検索できるのと同じように、
2種類以上の項目で対数時間で検索ができるようなコンテナはC++には無いですか?
分かりやすく言うと
class Board
{
 std::string name_;
 int id_;
 time_t time;   

 //メソッド省略
 //findByName(), findById(), findByTime() 
};

このようなクラスのインスタンスをたくさんコンテナに格納して、
findByName(), findById(), findByTime()のどれでも線形時間ではなく、
対数時間で結果のイテレータが帰ってくるようなコンテナが欲しいんですが。
>>850
標準だと無いと思うよ。
852デフォルトの名無しさん:03/10/13 15:10
後学のために伺いたいのですが、
「std::listの要素をサーチして、条件が一致したものをlistからeraseしていく」

…という作業を、普通に初期化した形のfor文で、
実現することは出来ないのでしょうか?
>>852
なぜforで? std::remove_ifじゃ駄目?

まあ、forで手書きするならこんな感じか:
typedef list<T> some_list_t;
some_list_t a_list;
for ( some_list_t::iterator p = a_list.begin(); p != a_list.end(); ) {
 if ( 条件 ) {
  p = a_list.erase(p);
 } else {
  ++p;
 }
}
下記のコードでなぜか最後の行が2回読み込まれてしまうようで、
最後の人が2人になってしまいます。
どう書き直せばいいのでしょうか?

ifstream ifs("address.txt");
vector<Person*> vec;
string name, address;

while(ifs)
{
 ifs >> name >> address;
 vec.push_back(new Person(name, address));
}
855852:03/10/13 15:44
>>853
レスサンクスです。いえ、なんの変哲もない順次サーチ=for文、
みたいな固定観念ができてしまっていて…。

for文の例、およびremove_ifの提示ありがとうございました。
remove_if使ったこと無かったです。これから調べてみます。便利ですね。
>>855
あ、listには専用にメンバ関数としてremove_ifがあるから
それ使うよろし
>>856
了解しました。追い銭重ね重ね感謝。
858854:03/10/13 15:56
自己解決しました。
こうやったらうまくいきました。

for(;;)
{
ifs >> id >> name;
 if(!ifs)
  break;
 boards_.push_back(BoardPtr(new Board(id, name)));
}
859854:03/10/13 15:57
間違えて元のコードを晒してしまいました…
>>850
std::set<boost::shared_ptr<Board> > index_by_name(pred(BY_NAME));
みたいなのをインデックスにしたい項目の数だけ作って全部に登録、とか?
861デフォルトの名無しさん:03/10/15 01:38
下記のコードですが、count_ifのところでsegfaultを起こしてしまいます。
どこがおかしいんでしょう?

#include <iostream>
#include <vector>
#include <algorithm>


static bool check_c(char input){
return input=='c';
}

int main(){
vector<char> sequence;
int c;
for(int i =0; i < 2; i++)
for(int j =0; j < 5; j++)
sequence.push_back( 'a' + j );
cout<<sequence.begin()<<endl;
cout<<endl;

c = count_if<vector<char>::iterator, bool(char)>(sequence.begin(), sequence.end(), check_c);
c = count<vector<char>::iterator, char>(sequence.begin(), sequence.end(), 'c');

cout<<c<<endl;
}
>>861
segfault以前にコンパイル通らないはずだから確かめてないけど。

> cout<<sequence.begin()<<endl;
ここだろうね。
不完全クラスに継承関係を明示する方法ってあります?

基底クラスのポインタに変換するのに、無理矢理reinterpret_castして、
とりあえず正常に動かすことは出来るのですが。
864861:03/10/15 01:56
>>862
その行をコメントアウトしても変化はありません。

実は、そこはただの手抜きで…
デバッガから見て、char* だったのでつけ足しただけのものなんです。
c = count_if<vector<char>::iterator, bool(char)>(sequence.begin(), sequence.end(), check_c);



c = count_if( sequence.begin(), sequence.end(), check_c);

にしてみる。
>>864
count_ifの中は追ってみたの?
なんにせよコンパイラもSTLの種類も示されないんじゃなんともね。
using namespace std;が抜けてるみたいだし。
>>861
count_if<vector<char>::iterator, bool(*)(char)>

bool(char)でコンパイル通るのが悪いと思うんだが。
>>867
bool(char)は正しい表記だったと思うよ
>>868
表記は正しいが、そのテンプレート引数だと関数型を値渡しすることになる。
関数型の値渡しができたっけ?
>>869
bool(char)はbool(*)(char)と同等だった気がする。
どこで見たのかは忘れたが。
871870:03/10/15 02:20
>>869
ゴメン、激しく俺の勘違い
>>867
それが正解でした。ありがとうございます。
コンパイラは、gcc-2.96-113 というRedhat Linuxのものです。

本来は通らないはずのコードだったのか…
gcc 3.3.1 (cygming) でテストしてみた。

↓は"redefinition of `int call(int (*)(int))'"
int call( int x(int) ){ return x(0); }
int call( int(*x)(int) ){ return x(0); }

↓はエラー無し
template< typename Function >
int call( Function x ){ return x(0); }
template int call<int(int)>( int(int) );
template int call<int(*)(int)>( int(*)(int) );

バグってるように見える。
>>861はgccかな?
VC++7.1

template< typename T > char const* typename_of( T r ){ return typeid( r ).name(); }
int main(){
std::cout << typename_of< bool(char) >( check_c ) << std::endl;
std::cout << typename_of< bool(*)(char) >( check_c ) << std::endl;
}

一つ目は関数が値渡しされてた。
式内ではどちらも関数ポインタとして扱われるもよう。
8.3.5 -3- より。
"After determining the type of each parameter, any parameter of type ``array of T'' or ``function returning T'' is adjusted to be ``pointer to T'' or ``pointer to function returning T,'' respectively."

というわけで、関数の引数においては>>870が正しいみたい。

14.8.2 -3- によると、
この変換がテンプレートのときにもいちおう関係はするようだが、
Noteとして書かれている
"f<int>(1) and f<const int>(1) call distinct functions even though both of the functions called have the same function type."
というのが怪しい。
変換後の仮引数がいっしょになるとしても、別々の関数としてコンパイルされるみたい。

で、gccで試したところでは、bool(*)(char)で実体化したほうは正しく動作するが、
bool(char)で実体化したほうのコードが死んでるっぽい。
仮引数リストは同じなので同じコードになるはずなのに、
bool(char)で実体化したときになんだかへんなコードが出る。クラッシュするコードかどうかは未確認。
876861:03/10/15 03:29
バグ持ち(bool(char))とバグ無し(bool(*)(char))のアセンブラ出力をdiffで並べてみました。
スタックに積んでルーチン呼ぶまでは一緒ですが、確かにルーチン内の処理が各々で異なっています。

--- bug.s Wed Oct 15 03:14:53 2003
+++ non-bug.s Wed Oct 15 03:13:55 2003
@@ -17,25 +17,21 @@
movl %eax, %eax
pushl %eax
.LCFI10:
- call count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type
+ call count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type
------------------------------------------(略)----------------------------------------------------
- .section .gnu.linkonce.t.count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type,"ax",@progbits
+ .section .gnu.linkonce.t.count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type,"ax",@progbits
.align 4
- .weak count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type
- .type count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type,@function
-count_if__H2ZPcZFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type:
+ .weak count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type
+ .type count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type,@function
+count_if__H2ZPcZPFc_b_X01X01X11_Q2t15iterator_traits1ZX0115difference_type:

877861:03/10/15 03:30
.LFB10:
pushl %ebp
.LCFI38:
movl %esp, %ebp
.LCFI39:
- subl $24, %esp
+ subl $8, %esp
.LCFI40:
- movl 16(%ebp), %eax
- movl 20(%ebp), %edx
- movl %eax, -8(%ebp)
- movl %edx, -4(%ebp)
- movl $0, -12(%ebp)
+ movl $0, -4(%ebp)
.p2align 2
.L54:
movl 8(%ebp), %eax
@@ -45,28 +41,28 @@
.p2align 2
.L57:
subl $12, %esp
- leal -8(%ebp), %edx
movl 8(%ebp), %eax
movsbl (%eax),%eax
pushl %eax
+ movl 16(%ebp), %eax
.LCFI41:
- call *%edx
+ call *%eax
x86のアーキテクチャ調べて来たよん。
結局、lealで関数ポインタを二重参照しているのが原因とわかりました。

count_if(8(%ebp),12(%ebp),16(%ebp)){
movl 16(%ebp), %eax
movl %eax, -8(%ebp)
leal -8(%ebp), %edx
call %edx
}
↓省略
count_if(8(%ebp),12(%ebp),16(%ebp)){
leal 16(%ebp), %edx
call *%edx
}
↓C++風に。
count_if(*a,*b, void (*func)()){
*(&func)();
}
879863:03/10/15 05:05
こっちも意見を聞かせてよ。
ソースがないから駄目なのか?

<B.H>
class B {};
<D.H>
#include "B.H"
class D : public B {};

<sub.cpp>
#include "D.H"
D dins;
D *d = &dins;

<main.cpp>
#include "B.H"
class D;
void func(B *b) {}
void main(void)
{
extern D *d;
func(d);
}

func(d)をfunc(reinterpret_cast<B *>(d))にすれば、
とりあえずちゃんと動くけど
そもそも不完全クラスの宣言に
class D : public B;
と言う意味を持たせて、reinterpret_castを使わずに済ます方法はないでしょうか?
>>879
D も B もわかって無いのに reinterpret_cast 以外のキャストをどうやって実行するの?
君の使ってるコンパイラが
static_cast< B* >( D* ) == reinterpret_cast< B* >( D* )
だとしても、他の環境でもそうとは限らない。

class D: public A, public B;
なら、多分君のコンパイラでも static_cast< B* >( D* ) するためには sizeof( A ) がわからないといけないはず。
>>879
D * dではなくて B * dでいいと思うけど。
そうすればmainからDについて知る必要ないし。
//base.h
class Base{public:
    virtual void print()=0;
    virtual ~Base(){}};
//Test.h
class Test:public Base{public:
    void print();}:
//func.h
Base * CreateTest();
//sub.cpp
#include "Base.h"
#include "Test.h"
#include "func.h"
#include <iostream>
Base * CreateTest(){
    return new Test;}
void Test::print(){
    std::cout << "Test::print()" << std::endl;
}
//main.cpp
#include "Base.h"
#include "func.h"
int main(){    Base * p=CreateTest();
    p->print();//Test::printが呼ばれる
    delete p;
    return 0;
}
まあ実際はboost::shared_ptrとかstd::auto_ptrとか使うだろうけど。
>881
ああそうか、自分の例で言うところの
extern D *d;
が、そもそもD *でなくてもB *で充分ですね。

何でこんな単純なことに気が付けなかったんだ?
とにかくこれで安心して眠れます。ありがとうございました。
つかぬ事をお伺いしますが、ローカルにおける文字列リテラルが
static constであることは言語規格上、保証されていますでしょうか?
>>883
ISO/IEC14882:1998(E)の規格票は買ったか?
ここは使ってみたか?

http://www.excite.co.jp/world/text/

まさか禿本持ってなかったりしないだろうな?
885B.S:03/10/17 01:23
禿々言うな。
お前等だって将来禿るかも知れないんだぞ?
C++のコードをJavaに書き直すことはできますか?
>>886
質問の意味がうまく絞れないんだが。
888886:03/10/17 13:39
1394カメラをJavaで動かしたいんですけど、
Javaでの動かし方がよくわかりません。
そのカメラには、付属のアプリケーションが付いており、
そのソースコードも付いてました。(VCとC++)
なので、そのコードをJavaに書き直してもらいたいのです。
889883:03/10/17 13:48
すまん、禿...もといStroustrup本に書いてあった。
「文字列リテラルの型はconst char[N]であり...
静的に割り当てられる。」
char*への代入が許されるから、定数として扱うかはベンダ依存かと思ってた。

ISO/IEC14882:1998(E)の規格票は持っていない。
つか欲しいんだけどどこで手に入る?
JavaってIEEE1394というデバイスを叩けたっけ?
>>890
叩けるよ!
892デフォルトの名無しさん:03/10/17 17:21
>>888
Linux とかならできるんじゃない?

Windows だと、そのへんは stream class mini driver をDirectShow の API が
ラッパするような形になってると思うんだけど、これは Java からは使えません。
>>889
> ISO/IEC14882:1998(E)の規格票は持っていない。
> つか欲しいんだけどどこで手に入る?
http://www.techstreet.com/cgi-bin/detail?product_id=49964 とかで買える。

もっと新しい ISO/IEC 14882:2003 もすでにpublishは
されてるはずなんだけど、どうやったら手に入るのかわからん。。。
894デフォルトの名無しさん:03/10/17 20:12
複数種類のクラスをしまっておけるバッファを作る時、

class A;
class B;

class Buf {
union {
A a;
B b;
};
}

コンストラクタのあるクラスだとunionは使えないんですが、何かいい手はないでしょうか?
マクロかboostか何かでmax(sizeof(A), sizeof(B))を取ってやるしかないんでしょうか。
>>894
cvsからboostの最新版を落としてきてboost::variant。これ。
896デフォルトの名無しさん:03/10/17 20:47
>>895
あれは使っているコンパイラでエラーが出ます。
898ファイル:03/10/17 21:18
読み込みたいテキストファイルの前半にに不必要な部分があるのですが、
その部分を除いてそのテキストファイルを読み込むことはできますか?
c言語初心者です、お願いします。
899デフォルトの名無しさん:03/10/17 21:28
【1:898】「C++」相談室 part23
むむ、オヌシ初心者だな。
>>889
C++に限らず
ここは知っておくべきでしょう

http://www.jsa.or.jp/
>>898
できます。
903ファイル:03/10/17 23:08
c言語の本をまだ一冊しか読んでないので、
よくわからないのですが、どうしたら不必要な部分を
除いて読み込むことができるのですか?教えてください。
>>903
ここはC言語のスレではありません
>>894
何でそんなことしたいのかが分からん。
自分で取ったバッファ内に A とか B のインスタンスを作りたいんだったら、
placement new 使え。
907894:03/10/18 01:03
>>895
なるほど、そんなもんがあるんですか…
しかしcvsから取ってくるのはちょっと恐いなぁ。せめてリリースされてるのに入ってればいいんだけど…

>>906
通信回りのバッファの扱いとか、パフォーマンスを気にする時のメモリ管理とか、
結構色々使います。
要するにunionが使いたいところです。
>>907
ならやっぱりplacement newでいいんでは?
909894:03/10/18 01:20
>>908
いや、placement newする前、どれくらいの大きさのバッファを確保するか、の方にからむ問題です。
>>909
template<int a, int b>
class Max
{
enum{Value = a > b ? a : b};
}

char buf[Max<sizeof(A), sizeof(B)>];
あっ、適当に書いたから間違いまくってるや・・・

template<int a, int b>
class Max
{
public:
enum{Value = a > b ? a : b};
}

char buf[Max<sizeof(A), sizeof(B)>::Value];
912894:03/10/18 02:03
>>910
そうですね、そんな感じでやるかなぁというのを894の最後に書いてみたんですが、
これだとちょっと嫌な点があって、アライメントで問題が起きる可能性があるんですよね。
まぁそれは、気にしながらclass Bufの中身の配置をするか、
複数クラスの入る場所の大きさにゆとりを持たせて先頭をちょっと調整するかだと思うんですが、
union的に扱えればずっと楽なのでそういうのないかなぁと。

あと、微妙に直観的じゃないのが嫌とか、実際には数10個のクラスを押し込むので
タイプリストを作って全体のMaxを取らなくちゃとか、微妙に腰が引ける感じが…
もちろんこちらは本質的な問題ではないんですけどね。
>>894
class A{};
class B{};

class Buf {
    char buf[sizeof(A)>sizeof(B)?sizeof(A):sizeof(B)];
public:
    A & GetA(){return *reinterpret_cast<A*>(buf);}
    A & GetB(){return *reinterpret_cast<B*>(buf);}
    template <typename T> T & Get{return *reinterpret_cast<T*>(buf);}
};

int main(){
    Buf o;
    new (&o.GetA()) A;
    o.GetA().~A();
    return 0;
}
//やや力押し気味、lokiのタイプリストとか使えば3つ以上のunionにも使えるだろうけど
classをバイナリコピーするの?
union で持たせるメリットが分からないなぁ。メモリ節約したいって話なら、
operator new を自前で書いて、使う側は void* ででも受けとけば良いん
じゃないの?
>union で持たせるメリット

だから、アライメントだろ?
917894:03/10/18 03:49
>>915
うーん、節約したいというわけではないけど。例えば…

class UserBase {
int user_defined_info;
};

class A : public UserBase {}; // class Bも同様

class Elm {
Elm *next;
union {
A a;
B b;
};
};

Elmは自分が使う側、ユーザはAだのBだのを使う感じで、
Elmのリストの中からuser_defined_infoを拾ってくる場合とか。
Elmの中にUserBase *を埋めておくだけという実装も可能だけど、それだと遅くなるとか、
Elmのサイズが揃ってるとメモリ管理が容易になるとか、
ライトバリアのかかったページにしかオブジェクトをおいちゃダメとか(これは今思いついただけだけど)、
まぁそれなりに状況は考えられますね。
そこまでかつかつに効率を求めるならクラス化する必要は無いと思うが。
919894:03/10/18 04:23
>>918
そいつはそうなんですけどね。

でもまぁ少しでも楽ができてかつバグの入りにくい形にしたいじゃないですか。
今のところ、単なるstructで逃げたり、char[MAX_SIZE]で逃げたり、
Base *で逃げたりしてるわけですけど、もう少し何とかならんかなぁと。

紹介してもらったboost::variantが早く標準にならないかなぁ。
variantはコンストラクタ・デストラクタはどういう扱いなのかな?
調べておくか…
class A{
std::vector<std::vector<double> > a;
public:
A(std::vector<std::vector<double> > b =
std::vector<std::vector<double> >()) : a(b) {}
};

という感じのクラスがあります。他にも関数がありますが、std::deque
でも出来る操作しか使っていません。このクラスのコンテナを
vectorとdequeから選んだり、コンテナの中の型をdouble以外の
ものにしたりするためにテンプレートを使いたいのですが、
やり方が分かりません。どうか教えてくださいませ。。
>>918
ゲームでも作るんですか?
何かそれっぽい気がしたんですけど。
template<class T, typname U>
class A{
T< T< U > > a;
とかか?
>>920
その程度ならtypedefしとくだけで1行書き換えれば変更できるようになる。
template<template<typename> class Container, typename T>
class A{
Container<Container<T> > a;
public:
A(Container<Container<T> > b =
Container<Container<T> >()) : a(b) {}
};

A<std::vector, double> hoge; // のように使う

でも>>923が正解な気がする。
>>922-924 有難うございます。
typedef std::vector Container;
typedef std::deque Container;
のどちらかを条件コンパイルするかコメントアウトするかして
クラス定義内でContainerを使うということですね。
ちなみに、Containerにstd::listを使いたいときは、>>924さんの
方法に部分特殊化を使えばいいのでしょうか?
>>917
> Elmの中にUserBase *を埋めておくだけという実装も可能だけど、それだと遅くなるとか、
本当に遅くなるか吟味した方が良いぞ。

特にキャッシュが少ない環境だと、大きなデータをリストでつなぐより、小さなインデクスを
配列にとってデータは void* の先においておく方がキャッシュミスが減ったりするし。
>>918
クラス化するなというか、コンストラクタ・デストラクタを自前で定義しなければ良いだけ
だよね。初期化用のメンバ関数を別に定義すれば良いだけ。

そういう形で使う以上、いずれにせよ A, B の確保・解放はユーザ側ではなく Elm 側で
行うんだろうし。
鈴木宗男氏が立候補を断念したそうだ。
>>928
誤爆orスレ違いだ。そう言う話題は↓でしろよ。
http://pc2.2ch.net/test/read.cgi/tech/1036811974/l50
930デフォルトの名無しさん:03/10/18 18:14
Visual C++ Runtime Library の メッセージボックスが開いて、
Runtime Error!
とメッセージを残して、強制終了(ノToT)ノ  なぜだ〜
931894:03/10/18 19:00
>>921
サーバとか、言語処理系とか、ゲームとか。

>>926
そうですね。まぁ>>917の例でAがでかくなったらUserBaseのみElmに入れて
A固有メンバはpimpleでしょうけど。
まプロファイル取らないとなんとも。

>>927
そうですね。その方法でいいと思いますが、
微妙に嫌なのは、デフォルトコンストラクタに相当するものが
void A::init() { UserBase::init(); ... }
と、必ずBaseクラスの初期化メソッドを明示的に呼ばなきゃいけない点かな。
932ちんげ:03/10/18 19:04
c++のソフトはwinnyで落とそう。
933デフォルトの名無しさん :03/10/18 21:28
クラスのメンバ関数で
引数に継承元のクラスのオブジェクトを入れたら
「シンタックスエラーerror C2061: 構文エラー : 識別子 'class1' がシンタックスエラーを起こしました。」
というエラーが出てしまいます。
何が原因なんでしょう?
後、シンタックスエラーって何ですか?
934デフォルトの名無しさん:03/10/18 21:38
>>933
文法違反。
シンタックス=文法論
セマンティクス=意味論
つーか、ぐぐれよそんくらい
【演習】次の例文に含まれる、シンタックスエラーとセマンティクスエラーをなるべく多く指摘せよ。
C++のソフトを
そんな悪いインターネットから落としたら
危険が危ないよ

>>931
なぜ placement new を嫌がるのかさっぱりわからん。

class C
{
public:
C( bool is_A ) : is_A( is_A ){ is_A ? (void)new(buf)A : (void)new(buf)B; }
~C(void){ isA() ? (void)asA().~A(): (void)asB().~B(); }
A& asA(){ return *reinterpret_cast< A* >( buf ); }
B& asB(){ return *reinterpret_cast< B* >( buf ); }
A const& asA() const{ return *reinterpret_cast< A const* >( buf ); }
B const& asB() const{ return *reinterpret_cast< B const* >( buf ); }
bool isA() const{ return is_A; }
private:
bool is_A;
char buf[sizeof( A )>sizeof( B ) ? sizeof( A ) : sizeof( B )];
};

asA() 等の呼び出しは最適化で消えてなくなり、直接アクセスしたのと同じことになる(VC7.1で確認)。
無理やり union 使ってキモイ思いするよりはるかに良い。
つか、unionって使ったことない。
そんなにメモリの節約がしたいのか?
http://www.cs.wisc.edu/~ghost/gsview/get45.htm
のコンパイルがうまくいきません。
readme.htmの指示どおりに調節したのですが、

"C:\Program Files\Microsoft Visual Studio\common\msdev98\bin\rc" -D_MSC_VER -D_Windows -D__WIN32__ -I"C:\Program Files\Microsoft Visual Studio\vc98\include" -i"C:\Program Files\Microsoft Visual Studio\vc98\include" -i".\src" -i".\srcwin" -i".\obj"
-i"en" -fo.\obj\gsvw32en.res .\srcwin\gvwin1.rc
指定されたパスが見つかりません。

というエラーが出ます。これはどうすればよいでしょうか?
>>939
指定したパスがあるかどうか確認したら?
941894:03/10/18 22:53
>>937-938
いやだからplacement newは当然使えるし、必要なら使うんですよ。unionであっても。
問題はそこじゃないんですよ。

937の例でいうなら、もしAとかBにアライメントが必要な要素が入ってたらダメでしょ?
別にメモリの節約のために使ってるんじゃないんですよ。
>>941
何が問題になるの?
>>937-938
union知らないなら黙ってた方が良いよ
>>942
アライメントの問題だと何回書かれたら分かるんだ?
>>944
それが、わからないから聞いてるんだ。
具体的にA、Bがどういう型のとき問題になるのか教えてちょ。
>>945
ちょっとアライメントを勉強したほうがいい

仮想関数もってるだけでダメになる場合もあるぞ
sizeof(A) って、アライメントとか仮想関数テーブルへのポインタ込みのサイズ返すんじゃないの?
>>947
そうだよ
>>948
じゃあ、何が問題なん?
普通に sizeof(A) 分のバッファ確保しとけば union なんて無くても placement new 出来るじゃん。
そのバッファのアライメントがAのアライメント要求を満たさなければならない。
>>950
それはコンパイラの制限でしょ?
952894:03/10/18 23:32
>>949
937の例でいうと、char buf[]の先頭がアライメントを意識して置かれていない可能性があるのが問題です。
>>952
static void* operator new(size_t) を適切に定義しておけ。
>>953
もうオマエは黙ってろよと、見当違いもいい加減にシロ

と894は思ってるよ、多分
>>951
意味がわかりません。
仮に、「それ」が「コンパイラの制限」だとしたら、
「普通に sizeof(A) 分のバッファ確保しとけば placement new 出来る」ことになるのですか?
956894:03/10/18 23:48
>>953
それで逃げる手が一つですね。ただしその場合は、Elm側からAにアクセスするたびに
必ずアライメント計算をしなくちゃならなくなります。

あ、もちろんbufのサイズは max(sizeof(A), sizeof(B))+アライメント分
にしておかないとダメです。

とりあえず
struct X {
char a;
char buf[8];
};
struct Y {
char a;
union {
char buf[8];
double d;
};
};
のsizeofでも見て、Y.dにアクセスしたい時の事を考えてみて下さい。
>>941
A とか B の placement new を、アライメント意識して書けば良いだけだと思うが……。
デフォルトだと「渡されたアドレスそのまま」返すことになってるけど、別にオフセット
調整しても良いんだし。

いちいちクラス毎に placement new 実装するのがダサイって話だと、そもそも
アライメント調整必須な段階で placement じゃない new も書き直す必要がある
(全部の処理系とはいわないが gcc 3.x とかはそう) から、手間は変わらないよ。
自動変数や static 変数だと、コンパイラ・リンカがよろしく取りはからってくれるけど、
new 使うとなると自前で工夫するのは大前提。
じゃあ、bufの前にintでもおいて、alignmentを意図すればいいじゃないか。
あるいは、charでなく、intでbufを確保する手もあるし。
え?なんでstatic void* operator new(size_t) を適切に定義することが回避方法になんの?

char buf[5454];
new(buf) A;

としてもその再定義したnewは呼ばれないぞ?
>>959
たぶん引数に void* を書き忘れてるんだと思うが。
>>958
世の中には8バイトアライメントや16バイトアライメントを必要とするものがあるのだよ
>>961
なら char を 7 つとか 15 とか挟んどけ。
963894:03/10/18 23:56
>>957
see 956
>>958, 962
see 912

>>959
その通りでした。文脈で明らかにplacement newの話だと思ったので
そう思い込んで返事しました。
>>962
アフォですか?
>union的に扱えればずっと楽なのでそういうのないかなぁと。

結局、「ない」ってのが答えだろ。
>>895-965 みたいなのを全て考えた上で boost::variant が
あるんだから、素直に使うかせめてソース読むかしようよ…
と思うんだがどうか。 1.31に入ることは確定してるから待つんでもいいが。 >>907
>>963
そもそも 894 の段階で、A, B が特定のアライメントを要求するなら、暗黙の Buf::new(size_t) を
使って new Buf できなくなってるワケだが……。
968894:03/10/19 00:23
>>966
おっしゃる通りです。私も別にboost::variantを使わないつもりはないのでそうします。
boostがどうやって回避してるか非常に興味深いし。

途中で「どうしてplacement newじゃダメなの?」とか言われたから
「まぁそういう疑問を持つ人も居るのかな?」とか思って返事したまでで。
特にゴネてるつもりはなかったんですが…

>>967
これ本当?unionなら大丈夫でしょ?そう信じて今まで書いてきたんだけど…
969937:03/10/19 00:30
お前らが騒いでる間に任意のアラインメントに対応できるコード書いた。
長いのでどっか貼り付けてくるからまってれ。
>>968
> これ本当?unionなら大丈夫でしょ?
処理系・ライブラリ依存だと思うが、俺の環境 (gcc 3.2 にベンダーがローカルな
パッチを当てたもの) だとダメだった。new Buf すると、単に

void *p = ::operator new(sizeof(Buf))

でヒープからメモリを持ってきて、この p をオフセット調整なしで使う。

だから 32byte aligned なメモリが欲しければ Buf クラスの operator new を自前で
定義して 32byte aligned なメモリを持ってくるように書き直す必要がある。

自動変数ならばコンパイラがスタックフレームポインタ調整を入れるし、static, global
変数はリンク時にリンカがメモリを適切に割り当てるから問題ないんだけど。
>>970
それは単に class A と class B にアラインメントが必要ないからではなかろうか。
>>971
そんなことはない。ちょうど先日はまった話なんだが

class Foo {
  u_char buf[1024] __attribute__((aligned(64))); // このメンバ変数は 64 バイトアライメント
};

といったクラスを用意して new Foo したら、buf か必ずしも 64 バイトアライメントされずに
困った。

アセンブラコードを出力させて調べたら >>970 みたいな状況だったので、Foo クラス内に

static void* operator new(size_t n) { return memalign(64, n); }
// memalign は指定したアライメントでヒープからメモリを切り出す関数

と追加して事なきを得た次第。
973937:03/10/19 00:55
http://do.sakura.ne.jp/~junkroom/cgi-bin/megabbs/readres.cgi?bo=lounge&vi=999294620&res=107

仮想関数の無いクラスのアラインメントは最初のプリミティブのアラインメントと等しいという仮定を置いてます。
>>972
PS2でつか?

struct aligned_t{};
namespace{ aligned_t aligned; }
void *operator new(size_t size,aligned_t,size_t n) {
return memalign(n,size);
}

int main(){
int *p=new(aligned,64) int;
}

こういう解決方法はどう?
>>974
> int *p=new(aligned,64) int;
それも良いアイデアだと思うけど、うっかり new(aligned, 64) Buf すべきところを new Buf しても
コンパイル時に検出できないのが悲しい。

C++ だと、ランタイムエラーよりはコンパイルエラーの方が何かと幸せだから。
CISCの派生CPUしか使った事がない
人ばかり見たいですね。このスレは。
でもその派生CPUでも高速化のためには
必要なんですけどね。
アライメント調整。
普通に struct A, struct B と

const int MAX_SIZE = Max<sizeof(A), sizeof(B)>::Value;
struct Buffer
{
enum{BUFFER_SIZE = MAX_SIZE / sizeof(int) + 1};
int buf[BUFFER_SIZE];
}

とか定義しといたら、A も B も Buffer もその先頭が
アライメント境界にくるように自動的に調整されないの?

調整されるんだったら、Buffer 型の配列作っといて、
それのアドレスを placement new に渡せば問題ないんじゃないの?
>>975
mallocで確保したメモリがどんなアライメント要求も満たすのが前提だから、
dlmallocにアライメント設定してmalloc置き換えるようにリンクさせればいいんじゃない?
>>977
Buffer はアラインメント境界に来るけど、それが A や B にとっても正しいとは限らない。
>>977
それだと、ふつうはintのアライメントを満たしてるだけだろな。
981894:03/10/19 04:34
>>970-972
ぐは。そうなんですか。かなりショック。
mallocにはアライメントは無理だってのは知ってたけど、
C++はせっかくnewに型渡してるのに意味ないじゃん。

情報ありがとうございました。
とりあえず週明けにstroustrup本にでも仕様を聞いてみますかねぇ。家にはない…
>>981
禿本には gcc の独自拡張である __attribute__ が載っているのか?
>>978
> mallocで確保したメモリがどんなアライメント要求も満たすのが前提だから、

処理系が知っているオブジェクトに対してはね。
__attribute__((aligned(64))); なんて物まで考慮に入れられないだろ。きりがない。
つーか、入れられても困るし。
>>981
> C++はせっかくnewに型渡してるのに意味ないじゃん。
そもそもユーザが明示的にアライメントを指定するのは、ANSI C++ 規格の範疇から
外れてるから。

ANSI C++ だと new Foo で呼ばれる operator new の型が

void* operator new(size_t n);

と決まっているので、アライメント値を渡す余地がない。
>>975
private: static void* operator new(size_t);
でOK?
>>985
それなら

public: static void* operator new(size_t n) { return memalign(64, n); }

で良いような気が。
次スレだぁ〜
>>988ゲットだぜ〜
>>989到着〜
>>990ハァハァ到着ぅ〜
なに〜先越されたーーーーー
おれがスレ立てるからおまいらは、待っててください。
このまま頂上目指すのみ
まだ見ぬ次スレへのリンクが紫色なのなんでだろぉ
それはおとズレた事があるから
998v(^・^)v:03/10/19 15:55
では閉じますか
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。