C++相談室 part56
..
666:デフォルトの名無しさん
07/09/20 15:16:10
>>650
ん?
プラグインやインタフェイス抽象は主として呼び出す側の再利用に繋がると思うけど。
呼び出される方の利用の仕方がまちまちだと、
呼び出す側はいちいちそれに合わせなくてはならないわけだけど、
インタフェイスや呼び出し規約(API)という形に抽象化し共通化しておくことによって、
呼び出し側を変更せずに機能を追加してゆくことができる。
もちろん呼び出される側を再利用する仕組みでもあるんだけど、
呼び出される側の再利用だけのためであれば単にAPI公開で十分なわけで。
667:デフォルトの名無しさん
07/09/20 16:37:16
template<class T> class A
{
public:
void (A<T>::*func)();
};
template<class T> class B
{
public:
static void (B<T>::*func)();
};
template<class T> void (B<T>::*B<T>::func)() = NULL;
template<class T, class U> class C
{
public:
void (U::*func)();
};
template<class T, class U> class D
{
public:
static void (U::*func)();
};
template<class T, class U> void (D<T, U>::*U::func)() = NULL;
クラスDのようにしたいんですけど、どなたかわかる方いませんか?
Visual Studio2005 SP1
668:デフォルトの名無しさん
07/09/20 16:38:31
ちなみにクラスD以外はビルドOKです
669:デフォルトの名無しさん
07/09/20 16:49:48
template<class T, class U> class D
{
public:
static void (U::*func)();
};
template<class T, class U> void (U::*D<T, U>::func)() = NULL;
こうだろ?
670:デフォルトの名無しさん
07/09/20 17:19:20
うぉ、ビルドとおった〜
ありがとう!!
昨日からずっと考えてたよ。
671:デフォルトの名無しさん
07/09/20 18:48:48
横からごめん
template<class T, class U> void (U::*D<T, U>::func)() = NULL;
ってどういう意味?
672:デフォルトの名無しさん
07/09/20 19:04:46
>>671
単なる、staticなメンバー変数funcの定義だよ。
NULLで初期化してるだけ。
673:デフォルトの名無しさん
07/09/20 19:05:53
void (U::*)() 型のstaticメンバ変数 D<T, U>::func を定義して NULL で初期化している
674:デフォルトの名無しさん
07/09/20 20:44:48
最近某入力デバイス共有ソフトのソースと某モデリングソフトのプラグインサンプルのソースと
見る機会があったんだけど
そのどっちも、どう考えても継承ツリーの最底辺、絶対継承されっこないし実際されてない
javaだったらfinalがついてもおかしくないクラスのメンバで
継承元の仮想関数をオーバーライドしている関数にvirtualがついてた
薄々感じてはいたんだけどどんな状況でもオーバーライドした関数にはその目印にvirtualをつけるっていう
暗黙のコーディングルール(というかおまじない?)のようなのが流行してるのかな?
それともvirtual修飾子の意味をほとんどの人が誤解している?
675:デフォルトの名無しさん
07/09/20 20:51:49
かなり昔から流行ってるよね。
676:デフォルトの名無しさん
07/09/20 20:56:41
C#のvirtual, overrideキーワードを見るよろし
677:デフォルトの名無しさん
07/09/20 20:58:33
>>676
C# なんか存在しない頃から流行ってるよね。
678:デフォルトの名無しさん
07/09/20 21:24:07
別にはやってないだろ
679:デフォルトの名無しさん
07/09/20 21:26:07
文法的にはどっちでもいいんだっけ?
680:デフォルトの名無しさん
07/09/20 21:27:37
多分継承元のクラスから関数宣言コピペして、面倒だからvirtual削除してないだけだろ。
681:デフォルトの名無しさん
07/09/20 21:40:33
virtualつけてもoverrideかどうかは分からない
ということに最近気づいた
682:デフォルトの名無しさん
07/09/20 21:41:32
overrideする側はvirtual要らないんだっけ
俺はいつもコメントにoverrideって書くけど
C#がうらやましいぜ
683:デフォルトの名無しさん
07/09/20 21:53:43
基本クラスがvirtualなら十分でそれ以降は任意だったと思うがドキュメントが出てこない。
継承が深くなるとvirtualかどうか確認するのにいくつもヘッダーファイルを遡ることになるから、
overrideしたところにもvirtualがあるとわかりやすい。
いま基本クラスと書いたが途中からvirtualっていうのもありなんだよな。
#include <iostream>
using namespace std;
class A { public: void Say() { cout << "hello A" << endl; }};
class B : public A { public: virtual void Say() { cout << "hello B" << endl; }};
class C : public B { public: void Say() { cout << "hello C" << endl; }};
int main(){
A *a = new C(); a->Say();
B *b = new C(); b->Say();
return 0;}
結果
hello A
hello C
684:デフォルトの名無しさん
07/09/20 21:59:49
一度virtual付ければ後は無くておk。
俺はドキュメントなんか鼻から探すつもりもありませんがw
685:デフォルトの名無しさん
07/09/20 22:01:01
あ、でもvirtualはいつも付けてる。
理由は>>683と一緒。
686:デフォルトの名無しさん
07/09/20 22:01:12
sealedが欲しい。途中から隠蔽w
687:デフォルトの名無しさん
07/09/20 22:06:18
#define public protected
688:デフォルトの名無しさん
07/09/20 22:26:15
とにかく、C#なんかより前から流行ってるよね。
689:デフォルトの名無しさん
07/09/20 22:35:25
>>686
sealedは継承禁止じゃね?
690:デフォルトの名無しさん
07/09/20 22:36:54
void func(const T& param)
{
T.Hoge();
}
っておかしい?
型Tは何かわからないからそのメソッドHoge()を呼ぶのはおかしい?
691:デフォルトの名無しさん
07/09/20 22:37:32
void func(const T& param)
{
param.Hoge();
}
の間違いでした
692:デフォルトの名無しさん
07/09/20 22:38:24
継承される事を前提に作ってないクラスはデフォルトでsealed(final)
って仕様だとうれしいんだけど
小規模で作ってる分にはいらないけどさ
693:デフォルトの名無しさん
07/09/20 22:42:09
大規模開発なら「派生型を作らないこと」とドキュメントに書けばいいような・・・
オープンソース物みたいにソースがドキュメントって感じのだと、
そういう言語によるディレクティブは役に立つとは思うけど。
694:デフォルトの名無しさん
07/09/20 22:56:14
>>689
メソッドに対するシールド。
class A { public virtual void Say() { .. ; }}
class B : A { public override sealed void Say() { .. ; }}
695:デフォルトの名無しさん
07/09/20 23:03:45
>>694
それ上書き禁止で隠蔽とはいわないんじゃねーかと。
696:デフォルトの名無しさん
07/09/20 23:09:03
>>695
やりたいことはこうよ。
class A { virtual F
class B : A { sealed F // Aに対するoverrideだが、この後の継承は上書き扱い(非virtual)になる。
697:デフォルトの名無しさん
07/09/20 23:10:36
こんなのはどうだっけ?
class A { public: void a() {}; };
class B : public A { public: template<typename> void a(); /*not implement*/ };
698:デフォルトの名無しさん
07/09/20 23:13:04
>>696
それは隠蔽とは言わんだろ。
AやBにキャストしたら そのまま使えるんだし。
Javaだと覆い隠し(shadowed)とか言ってるような。
699:デフォルトの名無しさん
07/09/20 23:18:46
目印なんだったらコメント使えばいいのになんでそれをトークン使って
プログラムそのものを変質させてしまう形でやってしまうのだろう
いったい誰がこんな風習を広めたのか気になって眠れない
700:デフォルトの名無しさん
07/09/20 23:19:09
>>672
ぁーなるほど。
void (U::*)()の、D<T,U>::funcを。ってことね。
了解しますた。さんくす
701:デフォルトの名無しさん
07/09/20 23:19:49
>>698
C#だとこれのことを隠蔽と言うだけどね。VBだとShadows。
sealedといったのは例えが悪かった。このnewがC++に欲しいという話。
class A { public virtual void Say() { .. ; }}
class B : A { public override void Say() { .. ; }}
class C : B { public new void Say() { .. ; }}
702:デフォルトの名無しさん
07/09/20 23:20:25
>>690-691
問題ない。
もしTがメンバHogeを持っていなければ、エラーになる。
それなんて動的言語と言いたいところだが、
そこはC++なんでコンパイルエラー。
703:デフォルトの名無しさん
07/09/20 23:43:21
>>701
悪い、それ隠蔽だわ。カプセル化の文脈で出てくるデータ隠蔽と勘違いしてた。
704:デフォルトの名無しさん
07/09/20 23:58:00
>>703
死ね
705:デフォルトの名無しさん
07/09/21 00:28:53
>>702
サンキュ
706:fIIPJstQwl
07/09/22 03:23:44
zghXa7 <a href="URLリンク(www.pic.ucla.edu) cock</a>
[URL=URLリンク(www.pic.ucla.edu)
<a href="URLリンク(www.pic.ucla.edu) cocks</a>
[URL=URLリンク(www.pic.ucla.edu)
<a href="URLリンク(www.pic.ucla.edu) dick</a>
[URL=URLリンク(www.pic.ucla.edu)
<a href="URLリンク(www.pic.ucla.edu) dicks</a>
[URL=URLリンク(www.pic.ucla.edu)
<a href="URLリンク(www.pic.ucla.edu) naturals</a>
[URL=URLリンク(www.pic.ucla.edu)
707:デフォルトの名無しさん
07/09/22 06:54:59
void func(int n)
{
void *a = (void*)new char[n];
/*...*/
delete[] (char*)a;
}
これってメモリリークを起こさずにうまく開放されるんでしょうか?
708:デフォルトの名無しさん
07/09/22 06:57:27
日本語がおかしい。
メモリリークは開放処理を試みた後に発生する。
709:Kusakabe Youichi
07/09/22 07:16:59
710:デフォルトの名無しさん
07/09/22 10:27:23
>>707
途中で例外が投げられてfuncを抜けるなどといった事態が起これば、
メモリリークするね。
711:デフォルトの名無しさん
07/09/22 11:06:37
間違って
スレリンク(tech板:770番)
に書き込んでしまいました。
宜しくお願いします。
712:デフォルトの名無しさん
07/09/22 11:22:09
お断りします
713:デフォルトの名無しさん
07/09/22 12:05:23
>>661
>つけられるconstは全てつけるべき。
自分が読んだ本ではconst使いましょうという感じだったので
今までconst使っていたのですが、会社でconstを使うなといわれました。
const推奨派とconst禁止派みたいなのがあるのでしょうか?
714:デフォルトの名無しさん
07/09/22 12:18:58
「(たまたま)変更されてない」って理由でつけると結局あとでconst外しまくる羽目になる。
「(概念や仕様から考えて)変更しない」って理由でつけるべき
715:デフォルトの名無しさん
07/09/22 12:23:08
外しまくる羽目になってでも現在付けられるものは
全部付けた方が分かりやすいという考え方もある。
716:デフォルトの名無しさん
07/09/22 12:34:26
>>713
const禁止とかどれだけ低脳なんだwww
取り合えず禁止になりうる理由として考えられるのは、
・API等に非constポインタを渡す必要があり、キャストの排除が最優先ルール
・クラスのconstメンバ関数にコンストラクタで代入できない
(↑もちろんメンバ変数の初期化は代入じゃなく初期化子並びを使うべきだが
C転向者が多くて教育コストがかかる)
・宣言が長くなるのでちょっと読みにくくなる
・メンバ関数の適切なconst指定も必要になってくるが、C転向(以下略
・既に非constで作り上げてしまった社内ライブラリを作り直せない。
・論理バグはコーディング工程で見付ける(コンパイルえらー)のではなく、
デバッグ工程で評価チームが見付けるものとして
スケジュールやら人員配分やらが組まれていて直せない。
・上位の人が勉強嫌い
717:デフォルトの名無しさん
07/09/22 12:39:23
>>711
実際にはnew[]するときに、sizeof (T) * 要素数よりも
もう少し余分に確保されている可能性がある。
主にデストラクタを呼ぶ回数を記録するため。
もちろん、delete[]ではそれも含めて解放される。
718:NXRoXAzeEmJXNM
07/09/22 12:50:13
IpHLIP <a href="URLリンク(www.pic.ucla.edu) nipples</a>
[URL=URLリンク(www.pic.ucla.edu)
<a href="URLリンク(www.pic.ucla.edu) tits</a>
[URL=URLリンク(www.pic.ucla.edu)
<a href="URLリンク(www.pic.ucla.edu) tits round asses</a>
[URL=URLリンク(www.pic.ucla.edu)
<a href="URLリンク(www.pic.ucla.edu) lesbians</a>
[URL=URLリンク(www.pic.ucla.edu)
<a href="URLリンク(www.pic.ucla.edu) pussy</a>
[URL=URLリンク(www.pic.ucla.edu)
719:デフォルトの名無しさん
07/09/22 12:51:29
>711
>delete[] は type* (この場合 char* )から
>sizeof(type) * (プログラマからは見えない、確保された要素数)
>の分だけのバイトを開放するという挙動でしょうか?
確実に言えるのは new[] で確保された領域が解放される、ということだけ。
サイズについては例えば 16 バイト単位とかに切り上げられてるかもしれない。
なお、delete[] については、静的な型と動的な型が一致することが要請されている。
> 14882:2003 5.3.5/3
>In the second alternative (delete array) if the dynamic type of the
>object to be deleted differs from its static type, the behavior is undefined.
で、気にしているだろうキャストについては、一度 void* にキャストした後、
元の型に戻した場合、値が一致することは保証されているので問題ない。
> 14882:2003 5.2.9/10
>A value of type pointer to object converted to “pointer to cv void” and
>back to the original pointer type will have its original value.
720:デフォルトの名無しさん
07/09/22 12:53:50
静的な型と動的な型の一致とは?
721:デフォルトの名無しさん
07/09/22 13:01:43
>>720
静的な型とはソースコード上の型、
動的な型とは実際の型のこと。
例えば、クラスDがクラスBを継承していたとして、
こういうことはやめてということ。
B* p = new D[n];
delete[] p;
722:713
07/09/22 13:05:16
>>714>>715>>716
なるほど、参考になります。ありがとうございます。
私のところではconstは一切禁止のようです。
「constを使うとコードの量が増えて読みにくい」
「constを使わずに読みやすいコードを書けば、コーディングミスも少ないから効率がよい」
という理由だそうです。
723:デフォルトの名無しさん
07/09/22 13:09:35
このスレッドがふさわしいかどうかわかりませんが、
質問させてください。
C++でリングバッファを作成しようと思っています。
Read PointerとWriter Pointer、そしてBufferを用意し、
Bufferから"複数バイト"を取得する、という処理です。
for(int i = 0; i < num; i++)
if(ReadPointer != WritePointer){
value = Buffer[ReadPointer];
ReadPointer = (ReadPointer + 1)%BufferSize;
}
else
break;
}
上記のように1バイトずつ読み込むならこれでいいとおもうのですが、
これでは1バイトごとに条件文+インクリメントが入るため避けたいです。
一気に複数バイトを読み込むことを考慮した場合、
"ReadPointerがWritePointer"を
越えないことを判断して、バッファを参照することが必要です。
複数バイトを読み込む場合を考慮したリングバッファを実現する
スマートなアルゴリズムはあるのでしょうか?
ReadPointer < WritePointerの位置関係からバッファ読み込みを
一気に行うことは容易ですが、ReadPointer > WritePointerの
位置関係からバッファ読み込みを一気に行う処理で詰まっています。
724:デフォルトの名無しさん
07/09/22 13:11:12
なんだか前世紀からタイムスリップしてきたみたいな職場だな。
組み込みでCを使ってるって言うのならまだ分かるが、
それでC++かよ。
725:デフォルトの名無しさん
07/09/22 13:15:23
#define N 7をconst N = 7;にしたところで
コードの量が増えるとは思わないけど。
constにも色々とあるけどさ。
726:デフォルトの名無しさん
07/09/22 13:32:05
>>707
auto_ptr 使えば。
727:723
07/09/22 13:33:38
>724
ご返信ありがとうございます。
特に組み込みなどではありません。
通常リングバッファはどのようにして実装するのが通例となっているので
しょうか?セオリーなどが確立しているのでしょうか?
728:デフォルトの名無しさん
07/09/22 13:42:40
>>726
new[]したものをdelete[]しないのは駄目だろ。
scoped_arrayとかshared_arrayとか結局Boost頼み。
729:デフォルトの名無しさん
07/09/22 13:46:48
>>727
BufferSize-ReadPointer 分だけ memcpy してから、
ReadPointer をゼロにして続きを処理すればよい。
C++ では普通テンプレートベースの汎用クラスを用いる。
高速化の必要がある場合には自前で書く。
(ココに高速化の必要がある場合には、リングバッファから取り出して
別の場所へコピーなどしないでバッファを直接読んで処理する方が
良いことが多いけど)
730:デフォルトの名無しさん
07/09/22 13:52:42
普通に一バイトずつ読み込めばいいだろが
一度に20バイトずつコピー出来ても大して変わらないだろ
731:723
07/09/22 13:57:09
>727
ご返信ありがとうございます。確かに2回に分けてBufferを取得すれば
可能です。
テンプレートベースの汎用クラスを用いる、というのはdequeなどを
使用するということでしょうか?
高速化を目指しております。
>(ココに高速化の必要がある場合には、リングバッファから取り出して
>別の場所へコピーなどしないでバッファを直接読んで処理する方が
>良いことが多いけど)
汎用クラスを用いず、地道にmemcpyなどを使ってデータを取得したほうが
よいのでしょうか?繰り返しの質問になってしまいますが。
732:デフォルトの名無しさん
07/09/22 14:00:44
>>721
>B* p = new D[n];
>delete[] p;
これダメなの? これに対応する為にvirtualデストラクタがあるんだと思ってたけど。
733:デフォルトの名無しさん
07/09/22 14:04:13
>>731
そうではなくて、ココをチューニングする必要があるのは
おそらく数M〜数十Mバイト毎秒の処理を行う場合なわけで、
そんなものをメモリ上でこっちからあっちへコピーする処理自体
無駄なのでやらないようにする、ということです。
例えば映像のデコーダの入力段でリングバッファを用いるような場合、
read(buf, n) などとしていちいちバイト列をコピーして取り出すのではなく、
char* peek(size_t n) のように直接内部のバッファを覗くための関数を用意して、
リングバッファ終端以外では直接バッファ内のバイト列を処理するようにする、等。
734:デフォルトの名無しさん
07/09/22 14:09:24
N 最後のナンバー
n番 からdバイトコピーするとする
if ( n + d - 1 > N){ memcpy(*,*, N - n - d); memcpy(*,*, n + d - N);}
else memcpy(*,*, d);
のようにすれば良い
735:723
07/09/22 14:11:23
>731
ご返信ありがとうございます。理解が乏しいかもしれないので
確認させてください。
readはmemcpyにより格納されたほかのバッファを利用する、ということで
peekはmemcpyで移さずにそのまま参照するということですね。
そして、リングバッファ自体はC++の汎用クラスを使って問題ないという
ことでしょうか?
>リングバッファ終端以外では直接バッファ内のバイト列を処理するようにする、等。
リングバッファ終端以外はpeak()、終端ではmemcpyなどを使って処理する、
ということでしょうか?
リングバッファの実装が初めてでなかなかイメージがわいてこない状況です。
何度も質問してしまって申し訳ありません。
736:713
07/09/22 14:13:21
低スキルなので>>723の質問の意味が分からなくて
>>724は私(>>722または>>713)に対するレスかと思ってしまいましたw
違ったのですねw
>>725
仮引数とかにconstをつけるとコードの量が増えて読みにくいから禁止なのだそうです。
737:724
07/09/22 14:13:58
>>727
いや、ひとつ上にレスしただけ。
738:723
07/09/22 14:18:17
>734
実際のサンプルを教えてくださってありがとうございます。
ぜひ参考にさせていただきます。
739:デフォルトの名無しさん
07/09/22 14:19:42
>>738
コードは間違ってる所あるけど、
終端を乗りこえていたら、分割して先頭からコピーすればいいだけ
740:デフォルトの名無しさん
07/09/22 14:30:07
>>735
Q1.前半 Yes. 後半 No.
Q2.
用途によります。動画のデコーダなどの場合は一度にリニアに
アクセスするのは高々数十バイト程度なので、一時的なバッファに
コピーしてそこのポインタを返す、あるいは内部バッファを余分に
確保しておいて、バッファ先頭にある続きのデータをそこに複製して
リニアに読めるようにする、等。
読む側の処理が簡単なものなら、終端をまたぐケースだけ
前半、後半に分けて処理するようにしても良いでしょう。
Q1. の後半とも関連するのですが、ただひとつ言えることは
ここを自前で実装すべきなのは、レアケースであって、その場合には
プロファイラやテストなどを行って確かめつつ最適なコードを書く必要があり、
定石みたいなものは無いということです。
ただまぁmemcpyは各社最適化されていて早いコードで実装されてるので、
チューニングしたいんだけど時間がないとかいうときには便利。
741:デフォルトの名無しさん
07/09/22 14:32:00
言い切ってやる。高速化すべきポイントはそこじゃない。
742:デフォルトの名無しさん
07/09/22 14:33:50
>>736
>724はあんた宛だと思うよ。
で、正直そんな会社は私の仕事関係なら出入り禁止にします。
743:デフォルトの名無しさん
07/09/22 14:34:05
>>736
>コードの量が増えて読みにくい
本当にこれだけの理由なら↓これらに当てはまりそうだ。
スレリンク(prog板)
スレリンク(prog板)
スレリンク(prog板)
constがない→何らかの変換が行われる、と予想してそのつもりで読むからな。
constがあることは読み手への助けになるのだよ。
744:デフォルトの名無しさん
07/09/22 15:14:29
>732
仮想デストラクタがある場合に OK なのはこっち。
B* p = new D;
delete p;
745:デフォルトの名無しさん
07/09/22 15:19:04
>で、正直そんな会社は私の仕事関係なら出入り禁止にします
内容の是非はともかくこういう言い方ってDQNじみてると思うんだが
746:デフォルトの名無しさん
07/09/22 15:21:32
スルーしる
747:デフォルトの名無しさん
07/09/22 15:23:02
>>744
これは仮想デストラクタがなくても領域自体は確保されるんですよね?
Dのデストラクタが呼び出されないのでコンストラクタとかでnewしててそれをデストラクタでdeleteしてる場合はだめだけど
748:713
07/09/22 15:28:43
>>737>>742
やはり私に対するレスなのですか。
では改めて・・・
>>724
組み込みではないけど、昔はCを使っていたそうなのでその名残でしょうか?
const以外にもいろいろ禁止されました。
私はfor文を
for(int i = 0; i < size; i++)
{
}
と書いていたのですが、これもダメで
int i;
for(i = 0; i < size; i++)
{
}
とか書かなければならないそうです。
理由は、私の書き方だと「速度が遅くなる」「使用するメモリが増える」からだそうです。私にはなぜそうなるのかよくわかりません。
>>743
確かに辞めたくなりますが・・・
いろいろダメだと言われても私は低スキル(頭が悪い)なので理由が良く理解できなくて
それでここで質問してみようかと・・・。
スレ違いでしょうか?
749:デフォルトの名無しさん
07/09/22 15:31:23
>>748
おめーと同僚や上司は頭悪いよ
空白は無視されるのが規則なんだよ 速度に違いは出ない
750:デフォルトの名無しさん
07/09/22 15:34:57
>>748
>理由は、私の書き方だと「速度が遅くなる」「使用するメモリが増える」からだそうです。私にはなぜそうなるのかよくわかりません。
寧ろ、あなたの書き方の方が速くなったりメモリが減るかも知れません。まぁ、大抵は同じでしょう。
いずれにしろ、一概には言えません。そんな根拠もないようなことを言っているようではお郷が知れると言うものです。
>確かに辞めたくなりますが・・・
私と一緒に働きませんか?w
>スレ違いでしょうか?
まぁ、宜しいのではないかと。
751:デフォルトの名無しさん
07/09/22 15:35:53
空白じゃなかった intの定義する位置か
752:デフォルトの名無しさん
07/09/22 15:37:51
>>749
>空白は無視されるのが規則なんだよ 速度に違いは出ない
i の宣言場所の違いが判らん香具師は黙ってらっしゃい。
753:デフォルトの名無しさん
07/09/22 15:41:37
関係ないけど
VCだと
for(int i = 0; i < size; i++)
って書いても
int i;
for(i = 0; i < size; i++)
こう書いてるように動くね
754:デフォルトの名無しさん
07/09/22 15:42:21
>>763
それはVC6とかの話じゃないのか
755:デフォルトの名無しさん
07/09/22 15:48:42
>>744 レスサンキュー
まじかー、紛らわしいというか不便だな。
B* p = new D[n];
delete[] dynamic_cast<D*>(p);
めんどくちゃいけど、これなら大丈夫だろうか。
まあ、ことさら >>732みたいに敢えて基底クラスのポインタで確保/解放する意味もないんだろうけどなぁ...
>>748
ちなみにそのfor文は上と下で i のスコープが変わると思うが、
for文に入る度にiが確保しなおされるとしたら速度変わるカモな。
使用メモリが増えるかどうかは分からん。
756:デフォルトの名無しさん
07/09/22 15:51:13
for文のiとかjってやっぱり仕事なんかで使うときもiやjなの?
757:デフォルトの名無しさん
07/09/22 15:54:34
>>755
>>753はVC(6以前)でスコープが同じになる事を言ってるんだよ
メモリ・速度云々は関係なく
758:デフォルトの名無しさん
07/09/22 15:57:58
>>756
i, jで何か文句あんのか?
759:デフォルトの名無しさん
07/09/22 15:59:46
>>756
単なるループ変数にたいそうな名前が付けられると
かえって読みにくくなるよね。
760:デフォルトの名無しさん
07/09/22 16:04:07
>>758
実際こんがらがって間違える事例を数件目撃したことがある。
慣れてくりゃなんともないが初学者にiやjで教えるのはどうかと思うんだよなぁ
761:デフォルトの名無しさん
07/09/22 16:07:07
>iとj
俺は目視デバッグでチェック項目の一つになってるわ
762:デフォルトの名無しさん
07/09/22 16:10:24
iやjにも元は意味があったろう
今じゃお決まりの変数として定着しているが
763:デフォルトの名無しさん
07/09/22 16:10:26
>>755
それだけなら動くだろうけど、
p経由で扱えるのは先頭要素だけ。
メモリ上にDのインスタンスが連続して並んでいるので、
p[1]が指す位置は、先頭の次の要素ではなく、
おそらくDの配列の先頭要素内の中途半端な位置。
764:723
07/09/22 16:14:51
>740, 741
ご返信ありがとうございます。
やりたいこととしては、参照用のリングバッファを書き込み用のリングバッファに
定期的に10KB〜300KB程度のデータを移したいと思っております。
(まず初めに最終的にやりたいことを書かなくてすいません)。
この場合は、終端をまたぐケースを考慮して(734さんのコードを参考、
2回の処理に分けるなどをする)、memcpyを使う、という方向で
考えたいと思います。
ただ一点、やはりC++の汎用クラスを使うのがいいのか、単純に
配列を使ってリングバッファを実装すればいいのか悩んでいるところです。
>ここを自前で実装すべきなのは、レアケースであって、その場合には
ここっていうのはreadとかpeak()のことですよね?
>言い切ってやる。高速化すべきポイントはそこじゃない。
この部分ばかりに注目するのではなく、
他の処理アルゴリズムをもっと最適化しろってことでしょうか?
確認ばかりのレスになってすいません。
765:デフォルトの名無しさん
07/09/22 16:15:05
>747
> これは仮想デストラクタがなくても領域自体は確保されるんですよね?
はい。
> Dのデストラクタが呼び出されないのでコンストラクタとかでnewしててそれをデストラクタでdeleteしてる場合はだめだけど
規格上は delete しちゃうと未定義動作。
>755
配列は polymorphic に扱わないというのが基本。理由は >763
766:713
07/09/22 16:16:59
>>750
>私と一緒に働きませんか?w
そう言われるとなんだか嬉しいですwでも私は足引っ張りまくると思いますよ?w
>>755
>for文に入る度にiが確保しなおされるとしたら速度変わるカモな。
なるほど、私の上司は速度についてはそれを言っていたのかもしれません。
私はiのスコープをループの中だけに限定するつもりで
そのように書いていました。(これも本で読んだので・・・)
>>756
私はiやjを使っています。
767:デフォルトの名無しさん
07/09/22 16:25:30
for (int iとint i; for(で最適化しても
速さに違いが出るようなコンパイラなんて
窓から投げ捨ててしまえ。
そんなことで速さに違いが出るのだったら、
設計思想的に、はなからこんな機能導入されていない。
768:デフォルトの名無しさん
07/09/22 16:28:36
基本的に
for ( int i= )の方が速いのでは?
その都度変数を確保すればレジスタに乗りやすいが、確保してあったままではHDDやメモリに乗っている可能性が高い
769:755
07/09/22 16:31:58
>>757
>>755は>>753に対して何か言ったつもりはないけど、
その話は(他のスレだったかで)聞いたことがアルよ。
>>762
多分 i = index のi じゃないかな。配列で使うことが多い気がする。
jは単にiの次の文字。
>>763,>>765
なるほど、このスレ見なければそのまま使ってたところだ。
勉強中でg++では問題なさそうに見えたからね。情報ありがとう!
>>767,>>768
まあ実際には気にするほどな差が出るとは思わないよね。
770:デフォルトの名無しさん
07/09/22 16:34:23
>>768
いつの時代のコンパイラ使ってるんだ? お前は。
771:デフォルトの名無しさん
07/09/22 16:36:43
intで差が出るのは糞コンパイラ未満だが、
intでは無くiteratorだった場合差が出ても果たして糞コンパイラ未満と言えるだろうか。
772:デフォルトの名無しさん
07/09/22 16:36:58
しかし、ある言語の常識を別の言語にまで持ち込むバカっているんだなぁ。
C(とCが全盛だった時代の貧弱なコンパイラ)ならまだ分かるかもしれないが、
今の時代のC++でやることじゃないだろ。
絶対に関わりあいたくないから、どこで働いているのか晒してくれないか?w
773:デフォルトの名無しさん
07/09/22 16:38:09
大丈夫
君には入社できないから
774:デフォルトの名無しさん
07/09/22 16:39:42
>>771
前提を変えるなアホ。
そのイテレータのコンストラクタが100MBぐらいメモリを確保するんだったらどうだろうかとか、
いくらでも話を広げられるじゃないか。
775:713
07/09/22 16:41:07
>>772
>絶対に関わりあいたくないから、どこで働いているのか晒してくれないか?w
私の会社ですか?それは勘弁してくださいw
776:デフォルトの名無しさん
07/09/22 16:42:05
ぶっちゃけ日本のC++PGの何割がEffective C++とか読んでんだろうな
板違い気味だけど
>>771
俺だったら滅茶苦茶速度に過敏なコードだったら
例え速度が全く等しくてもポインタにする
777:デフォルトの名無しさん
07/09/22 16:47:58
i,j については↓の「暗黙の型宣言による伝統的・慣習上の変数命名規則の誕生」の項を参照。
Wikipedia項目リンク
778:デフォルトの名無しさん
07/09/22 16:52:18
>>768
基本的に、C/C++ではローカル変数は全てスタックに確保される。
その場合、その確保作業は関数突入時にのみ行われる。
従って、次のようなコードはどちらも確保に伴うコストに変わりはない。
但し、後者の場合は最初のiと後のiで違うメモリを確保する可能性は、ある。
--
void func()
{
int i;
...;
for (i = 0; i < N; ++i) ...;
...;
for (i = 0; i < N; ++i) ...;
}
void func()
{
...;
for (int i = 0; i < N; ++i) ...;
...;
for (int i = 0; i < N; ++i) ...;
}
--
# 勿論、後者もiの有効範囲が重ならないことは容易に判る訳で、真っ先に最適化の対象にはなりそうだが。
779:デフォルトの名無しさん
07/09/22 16:53:29
>>776
私だったら、滅茶苦茶速度に過敏なケースにコンテナは使わないな。
780:デフォルトの名無しさん
07/09/22 16:57:00
>>778
>後者の場合は最初のiと後のiで違うメモリを確保する可能性は、ある。
つまり関数突入時に二つのiを確保するということかな?
だとすれば、速度/メモリ量共に影響があるじゃないか!
781:デフォルトの名無しさん
07/09/22 16:58:44
>>776
可読性も決して軽視出来ない要素だろ・・・条項
782:デフォルトの名無しさん
07/09/22 16:59:53
>>780
馬鹿だな、全く最適化を考慮しない場合の話だぞ。
それに、速度には全く影響ないじゃないか。
783:デフォルトの名無しさん
07/09/22 17:03:16
>>782
>馬鹿だな、全く最適化を考慮しない場合の話だぞ。
その場合のつもりで言ったんだ。
>それに、速度には全く影響ないじゃないか。
すまん、勘違いだった。
784:713
07/09/22 17:04:42
>>776
>ぶっちゃけ日本のC++PGの何割がEffective C++とか読んでんだろうな
Effective C++は持っていますが難しくて分からないところがたくさんありました。
私の会社ではconstのことを考えるとEffective C++とか読んでるのは私だけですかねぇ・・・。
785:デフォルトの名無しさん
07/09/22 17:06:27
>>780
お前の環境についてはしったこっちゃないが。
俺様の環境ではスタックポインタを4つ減らすか8つ減らすかの違いでしかないな。
あと俺様のコンパイラはお前以上に頭がいいので、ひとつしか使わないがな。
786:デフォルトの名無しさん
07/09/22 17:08:22
頭のいいコンパイラなら
そもそも使わない分までスタックポインタを移動しない。
787:713
07/09/22 17:39:37
あと、他にも会社で禁止にされたことがあります。
ブロック内でfor文やif文など以外のブロックを作成してはならないと言われました。
理由は「行数が増えたりして読みにくくなる」「変数は関数の先頭で宣言したほうが読みやすい」からだそうです。
私はこんな感じで { } を使うことがたまにあります。
void hoge(void)
{
{
}
}
私の会社では禁止なのですが、この書き方は一般的なのでしょうか?
皆さんはこのように { } を使うことはありますか?
788:デフォルトの名無しさん
07/09/22 17:45:51
>>787
デストラクタの実行タイミングを細かく制御したいとき(セマフォなどの共有リソースを使ったりとか)には
よくそういう包み方することはあるな。
789:デフォルトの名無しさん
07/09/22 17:46:42
>>787
変数を使う範囲を明示するために頻繁に使うよ。
その会社には仕事を頼みたくないな…。
790:デフォルトの名無しさん
07/09/22 17:47:53
>>787
俺はあまりやらない。その内側のブロックを関数化するかもしれない。
791:デフォルトの名無しさん
07/09/22 17:49:02
>>713
そんな会社辞めちまえ、ダメプログラマにされるぞ
792:デフォルトの名無しさん
07/09/22 17:49:28
やっぱり出入り禁止だw
>>787
>理由は「行数が増えたりして読みにくくなる」「変数は関数の先頭で宣言したほうが読みやすい」からだそうです。
この辺でお郷が知れる。
こう書く人が多かったりしない?
--
FILE * fp;
fp = fopen(...);
793:デフォルトの名無しさん
07/09/22 17:55:17
>>713
尻穴みたいな井の中の蛙になりたくないなら
学習の意欲のあるうちに辞めちまったほうがいい
あるいは部署変えてPG以外の業務勉強したほうがためになりそう
794:デフォルトの名無しさん
07/09/22 18:01:32
>>787
それは禁止されてていい
795:デフォルトの名無しさん
07/09/22 18:03:07
ある意味そのレベルでC++使ってるっちゅーのが感動的だナ
C++といいつつ実質Cとして使ってる制御系か?
VC++6.0以前とMFC使ってる業務系か?
制御で「const使うな」はありえんか
796:デフォルトの名無しさん
07/09/22 18:14:00
これで「クラスって何、おいしいの」だったら傑作なんだが。
797:デフォルトの名無しさん
07/09/22 18:16:17
どこが?
798:デフォルトの名無しさん
07/09/22 18:20:00
>>787
関数内の { } は変数などのスコープを限定するツールとして役に立つよ。
スコープを限定するのがどういいのかは、話すと長いが...
グローバル変数がよくない(誰がどういうタイミングでアクセスするのか
把握できなくなる・しにくくなるから)のとおおよそ同じ理屈。
根拠のない(しかもわりと間違っている)ローカルルールが多いね。
チーム内で1人で反抗してもしょうがないとは思うけど、
ちゃんとしたプログラマになるつもりなら、
後学のためにまず初学者向けの良書を読んでおくことをお勧めする。個人でね。
Effective C++よりももうちょっと易しいものから読んだ方がよさげ。
...って何がいいんかね。C++ Coding Standardsってのも良書でお勧めできるけど、
やっぱりちょっと早いような。
799:デフォルトの名無しさん
07/09/22 18:21:02
そんな長い関数を書くなよ
800:713
07/09/22 18:24:51
皆様、レスありがとうございます。
>>792
いいえ、C++ Builderを使っているのでファイルにアクセスするときは
みんなVCLを使っていると思います。
VCLに関連して「Delphiを使うかもしれないからC++のライブラリに依存してはならない」
という理由でSTLも禁止になりました。
STL禁止は守れそうにありません。
>>794
その理由は
「行数が増えたりして読みにくくなる」「変数は関数の先頭で宣言したほうが読みやすい」からですか?
>>795
前述のようにC++Builderを使っています。
パソコンからいろんなものを制御しています。
801:デフォルトの名無しさん
07/09/22 18:29:48
>>800
悪いことはいわんからとっとと逃げ出したほうがいいんじゃないか、その会社。
正直言ってアホしかいねーだろ、どうみても。
802:デフォルトの名無しさん
07/09/22 18:34:13
なんか凄いことになってるな。
>>773
これなら刺身の上にタンポポを乗せる仕事のほうがまだマシだ。
803:デフォルトの名無しさん
07/09/22 18:36:11
標準ライブラリを使っちゃいけないってどんだけー
804:デフォルトの名無しさん
07/09/22 18:40:08
まあ、仕事でやってるとわけ分からんルールは多いね。
なぜそするの? → 以前からそうだから。
こう変えたほうが良いのでは? → 今までこれでうまく言っているのだから変えるべきではない。
ということが多すぎ(--;
とりあえず社内ルールだからと割り切ってるが、本来どうあるほうが良いのかという勉強は欠かさないつもり。
805:デフォルトの名無しさん
07/09/22 18:40:12
STL禁止か……もはやC++じゃないな。
テンプレートは使えるんだろうか。
というかなぜC++を使っているんだ。
もういっそのこと全部Delphiでいいだろ。
806:デフォルトの名無しさん
07/09/22 18:45:25
この手の社内ルールというのは、
それを決めた時点では妥当だったりそれなりの理由があったりするものだが、
その後状況が変わってもそれを盲信して変えないという状況に陥りがちなんだよな。
なぜそうするのかが忘れさられて、ただルールだからという理由で守られ続ける。
807:デフォルトの名無しさん
07/09/22 18:47:45
STL禁止や標準ライブラリ禁止って組み込みだったらそれなりにあることだと思ってたけど?
808:デフォルトの名無しさん
07/09/22 18:54:41
>「Delphiを使うかもしれないからC++のライブラリに依存してはならない」
コピペ改変コーディングしか出来ない奴が大半と見た
809:713
07/09/22 19:04:23
>>805
>テンプレートは使えるんだろうか。
テンプレートは上司が知らないので使いすぎると
また禁止になる可能性があると思います。
>というかなぜC++を使っているんだ。
>もういっそのこと全部Delphiでいいだろ。
これは私の推測ですが、
C言語は知っている
↓
Windowsの時代になりGUIのソフトを作成しなければならない
↓
Visual C++は難しいのでDelphiを使う
↓
C++Builderが発売
↓
慣れたC言語を使いたくてC++Builderを使う
と、こんな感じではないかと・・・。
>>807
私の会社では組み込みのプログラミングはありません。
810:デフォルトの名無しさん
07/09/22 19:16:04
っていうか組み込みの仕事だっていうから、コンパイラをさらしてくれないと何とも言えない。
上司や同僚が親切に「(このコンパイラでは)〜の方が速くてコンパクトなコードが出る」と
教えてくれてるのかもしれないし。
811:デフォルトの名無しさん
07/09/22 19:37:16
その上司は各種ライブラリのリファレンスもconstウゼーな、
とか言いながら読むんだろうな。
812:デフォルトの名無しさん
07/09/22 19:38:53
だんだん「ム」ではなく「マ」の話題になってきたような気がする。
813:デフォルトの名無しさん
07/09/22 19:44:27
あとでっかい機能といえば例外処理と名前空間だろうか。
Delphi移植論でいけば例外処理はありとなってほしいところだが。
814:デフォルトの名無しさん
07/09/22 19:45:11
コーディング規約やその他のコーディングスタイルは、本来プロジェクトごとに決めるべき。
企業としての品質を維持するために共通ルールを設けるのは構わないが、ある程度の幅を持たせておき
その幅をプロジェクトごとにきめる形にするのがいい。
設計段階でのレビュー作業や、コードレビュー、プロジェクト完了時点での反省会議などをきちんとやれる会社でさえ、
コーディングルールは決まっていないことが多いから仕方ないことなのかも知れないが。
815:デフォルトの名無しさん
07/09/22 19:48:48
その辺のC++の「新機能」って初出はARMだっけか?
1990年だからもう20年近く前になるんだが
816:713
07/09/22 20:27:49
>>810
え?>>810は私に対するレスですか?
私はパソコンで使用するソフトを作成しているので
組み込みの仕事では無いと思います。
ついでにコンパイラはC++Builderのそれです。
>>813
名前空間は使っているところをまだ見られていないと思うので分かりません。
上司が名前空間という機能を知っているかどうかも分かりません。
例外処理は勉強不足で私自身分かっていないのでなんともいえません。すみません。
>>814
私の会社はプログラマが少ないせいなのか、決まったルールは無いようです。
入社して間もない私が今まで誰もしなかった書き方をしていたので
上司は他の人も読めるようにしたかったのではないでしょうか。
また、コードレビューや反省会議といったものは特に無いようです。
817:デフォルトの名無しさん
07/09/22 21:01:47
レビューもなく環境的な制限もないのにあれ使うなこれ使うなとか言われるのはやだな。
818:デフォルトの名無しさん
07/09/22 21:05:08
完全に言語/技術の話じゃなくて「いかに俺の会社の上司がドキュソか」っつー
話になってるな
そういうのはマ板でやってくれんか
819:デフォルトの名無しさん
07/09/22 21:29:57
const_<int> i(0);
820:デフォルトの名無しさん
07/09/22 21:45:55
なんかこの流れキモくね?
821:713
07/09/22 21:59:46
納期に間に合わないので明日は出勤します。
>>818>>820
すみません。
>>819
それはconstのかわりにということですか・・・。
見つかるとそれも禁止になると思います。
スレ違いになってきたようなのでこの話はこのへんで止めます。
レスして下さった皆様、今日はありがとうございました。
822:デフォルトの名無しさん
07/09/22 22:23:46
std::ostreamに空白文字 ' ' をn個出力する処理の、素敵な、シンプルで高速な書き方を教えてください。
823:デフォルトの名無しさん
07/09/22 22:25:24
for(int i=0;i<n;i++) { os << ' '; }
824:デフォルトの名無しさん
07/09/22 22:27:55
>823
現状はそれですが、プロファイラが遅いと言っています。
825:デフォルトの名無しさん
07/09/22 22:28:04
こうかな
cout << setw(n) << ' ';
826:デフォルトの名無しさん
07/09/22 22:32:57
>825
ソレダ
どうもありがとうございました。
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5384日前に更新/205 KB
担当:undef