トップページ⇒tech
1001コメント351KB

【初心者歓迎】C/C++室 Ver.44【環境依存OK】

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2007/11/03(土) 00:20:13
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.43【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1190860744/l50
【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
0478デフォルトの名無しさん2007/11/24(土) 23:18:32
>>477
OutputDebugStringA
0479デフォルトの名無しさん2007/11/24(土) 23:51:42
OutputDebugString(_T("hoge"));
の方が好みだなー
0480471 2007/11/25(日) 00:00:46
>>478さん

OutputDebugStringA !!目から鱗ありがとうございます!!!

コンソールにも出したかったのですが、これは一応自己解決しましたのでご報告。

FILE *stream;
if (!::AttachConsole(ATTACH_PARENT_PROCESS)) { //XP以降はアタッチ
::AllocConsole(); //無理な場合は新たに開く
}
freopen_s(&stream, "CON", "r", stdin); // 標準入力の割り当て
freopen_s(&stream, "CON", "w", stdout); // 標準出力の割り当て

cout << "hoge" << endl;

::FreeConsole(); //アタッチ解放

以上です、ありがとうございました!
0481デフォルトの名無しさん2007/11/25(日) 00:02:56
イベントログに出力しちゃいなYO!
04824732007/11/25(日) 01:26:22
>>473
自己解決しました
0483デフォルトの名無しさん2007/11/25(日) 13:11:04
    if ("a" < "b")
        cout << "ok" << endl;
    else
        cout << "ng" << endl;

この場合はokと表示されるのですが

    if ("aa" < "bb")
        cout << "ok" << endl;
    else
        cout << "ng" << endl;

この場合はngと表示されます。

aのほうが文字コードが小さいのでokと表示されることを期待しているのですが
なぜこうなってしまうのでしょうか?
0484デフォルトの名無しさん2007/11/25(日) 13:15:39
文字列リテラルを不等号で大小比較比較しても、それはただ文字列リテラルの値(=アドレス値)の
大小を比較しているだけだよ。
文字順の比較をしたければ strcmp などを使え。

上記の意味が分からなければ、まずはちゃんとした入門書などを読んだほうがいい。
0485デフォルトの名無しさん2007/11/25(日) 14:39:57
string
0486デフォルトの名無しさん2007/11/25(日) 15:45:20
>>483
それは文字列が格納されているメモリアドレスを比較してるだけ
文字列の内容を比較したいなら strcmp を使え
0487デフォルトの名無しさん2007/11/25(日) 16:09:55
>>483
つ[ std::string("aa") < std::string("bb")]
0488デフォルトの名無しさん2007/11/25(日) 16:17:47
構造体を色んなソースで使いまわしたいのですが上手くいきません。

 共通ヘッダ: typedef struct TAG TYPE_NAME;
          TYPE_NAME nantoka1;

   ソースA: struct TAG { int a; int b; };

   ソースB: nantoka1 = { 3, 5 }

こんな風にしてみたんですが、ソースBは 'TAG' を認識してくれません。
どうすればいいでしょうか
0489デフォルトの名無しさん2007/11/25(日) 16:27:38
>>488
共通ヘッダ:
 struct TAG { int a; int b; };
 extern struct TAG nantoka1;
ソースA:
 いらない。
ソースB:
 struct TAG nantoka1 = {3, 5}
 
0490デフォルトの名無しさん2007/11/25(日) 16:39:43
リンクが絡まりそうなヘッダだな。
nantoka1が必要なソースでexternするようにした方がいいと思う。
04914882007/11/25(日) 17:05:02
489さんのやり方でやってみたら上手くいきました。ありがとうございます。
0492デフォルトの名無しさん2007/11/25(日) 23:01:29
ねーねー
連結リストの先頭のHeadをポインタで宣言しないのはどうして?
ポインタで宣言したほうが構造体分無駄にならなくなくない?
0493デフォルトの名無しさん2007/11/25(日) 23:03:56
boost初心者です。

以下がVC+2005ではコンパイル・実行できますが、Linux g++ 4.0ではコンパイル
できません。エラーコードはテンプレートだらけでよくわかりません。
何が違うのでしょうか?

#include <iostream>
#include <boost/bind.hpp>
using namespace std;
using namespace boost;

int someKeisan(int n1, int n2)
{
 return n1 * n2;
}

int main()
{
 cout << bind(someKeisan, _1, 10)(6) << endl;

 return 0;
}
0494デフォルトの名無しさん2007/11/25(日) 23:06:44
>>492
ポインタで宣言できるなら、そうすればいいんじゃないか?
むしろ、先頭用の構造体を持ってる実装のほうが珍しいと思うが。
0495デフォルトの名無しさん2007/11/25(日) 23:11:42
>>494
そうなの?
Googleとかで引っかかるサイトだと普通に宣言してるのが多いから
そういうもんかと思ってたよ
何にしてもありがとう
疑問が一つ解けたよ
0496デフォルトの名無しさん2007/11/25(日) 23:16:08
>>493
Cygwinでg++ 4.1.1だけどコンパイルできたよ。
0497デフォルトの名無しさん2007/11/25(日) 23:17:45
>>495
「連結リスト」でググって一番上にあるサイトからポインタで実装してるぞw
その次のはダミー作ってたけど。
0498デフォルトの名無しさん2007/11/25(日) 23:18:38
>>496
ヘッダーも存在してるし、
実装が未熟なんですかね?
0499デフォルトの名無しさん2007/11/25(日) 23:22:47
ちなみに
OS : Fedora Core 4
g++ 4.0.0でデフォルトのものを使ってます。

0500デフォルトの名無しさん2007/11/25(日) 23:26:35
>>499
boostを入れてないってことないか?
0501デフォルトの名無しさん2007/11/25(日) 23:29:22
>>500
functionやtokenizerは動作しますんで
boostは入ってると思います。
/usr/include/boostにhppファイルはあります。
0502デフォルトの名無しさん2007/11/25(日) 23:41:10
うちのFedora7でもだめだった。
0503デフォルトの名無しさん2007/11/26(月) 00:02:09
>>495
先頭要素が必ず存在するようにしたほうがコードを簡略化できるケースもあるから
あえてポインタではなく構造体を使用するということもあるよ。
よほど大きな構造体でない限り、高々1個を省略することは大きな意味はないから。
0504デフォルトの名無しさん2007/11/26(月) 00:22:16
>>502
そうですか。
tr1/functionalヘッダとtr1::placeholdersを指定しても
ダメでした。
VC++で我慢します。
05055022007/11/26(月) 01:38:50
気になったんで試してみた。同じ g++でも環境によって違うみたい。FreeBSDでは成功した。
以下結果と環境だけ。エラーメッセージは長いので省きます。

[FreeBSD 6.2R : コンパイル成功]
>GNU C++ version 3.4.6 [FreeBSD] 20060305 (i386-undermydesk-freebsd)
> compiled by GNU C version 3.4.6 [FreeBSD] 20060305.
>GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096

[ Fedora7 : コンパイル失敗 ]
>GNU C++ version 4.1.2 20070925 (Red Hat 4.1.2-27) (i386-redhat-linux)
> compiled by GNU C version 4.1.2 20070925 (Red Hat 4.1.2-27).
>GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=129178

[ Cygwin : コンパイル失敗 ]
>GNU C++ version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) (i686-pc-cygwin)
> compiled by GNU C version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125).
>GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072


コンパイル失敗した二つは同じエラーが出てる。
>a.cpp:13: error: no match for call to ‘(boost::_bi::bind_t<int, int (*)(int, int), boost::_bi::list2<boost::arg<1>, boost::_bi::value<int> > >) (int)’
05065032007/11/26(月) 01:49:36
boostのversionの問題かも。
以下boost/version.hpp 内の定義比較。

[FreeBSD 6.2R]
>#define BOOST_VERSION 103401
>#define BOOST_LIB_VERSION "1_34_1"

[Fedora7][Cygwin]
>#define BOOST_VERSION 103301
>#define BOOST_LIB_VERSION "1_33_1"

コンパイル成功したFreeBSDだけ、1_34_1 だ
05075022007/11/26(月) 01:51:57
上ネーム欄間違い、503じゃなくて502。

これがboostのバージョンが原因なら、boostバージョンアップで解決するかもね。
0508デフォルトの名無しさん2007/11/26(月) 02:06:32
cout << bind(&someKeisan, _1, 10)(6) << endl;

にしたらどう?
05095022007/11/26(月) 02:19:41
Cygwin に boost 1_34 入れてみたら、コンパイル通った。
なんか修正されたんだな。リリースノートどこにあるんだろ・・・。

とりあえずすっきりした。これで寝れる。

>>508
だめ。
0510デフォルトの名無しさん2007/11/26(月) 15:06:00
VS2005スレで聞いたほうがよいのか迷いましたが、まずはこちらで質問させてください
VS2005でC++を使って組んでいるのですが、「関数宣言はされているものの実態が存在しない」というリンクエラーが大量に出て困っています。
(私の言う関数とは、クラスの関数。つまりメソッドです)

自分で作ったのなら当然実体も定義するのですが、これは他人のソースで、さらにその人は「とりあえずヘッダに必要そうな関数をかたっぱしから宣言しておく」人のようです。

実体が存在しない関数に関しては「一度も呼び出した無い」そうで、コンパイルオプションだかで「一度も呼び出してない関数は、宣言もろとも無視する」ことができる(そうやって実行ファイルを作りテストした)そうなのですが、どうすればよいのでしょうか?
(残念ながら、そのソースを書いた人自身に質問することができないのです)
0511デフォルトの名無しさん2007/11/26(月) 15:08:02
>>510
警告じゃなくて?
0512デフォルトの名無しさん2007/11/26(月) 15:18:44
>>510
仮想関数の場合は実体は必要だけどね。
0513デフォルトの名無しさん2007/11/26(月) 15:19:50
まさかデフォルトコンストラクタ?
0514デフォルトの名無しさん2007/11/26(月) 15:22:34
>>511-513
すいません、自己解決しました
>>510は友人の悩みをヒアリングして私が(私の体験っぽく)書き込んだのですが、511の指摘で「確かに警告ならわかるんだけどなぁ」と思い私自身でソースを調べてみました。

単に友人が渡されてるlibファイルを組み込んでいないだけの話でした(ちなみにその関数はちゃんと呼び出されていました。呼び出されていたからこそ警告ではなくエラーとなっていました)
お騒がせしてすいませんでした
0515デフォルトの名無しさん2007/11/26(月) 15:25:21
>>514
そんなミスは誰でもよくやることですから気にしなくてよいのですよ。

と、ご友人にはお伝えください。
0516493=5042007/11/26(月) 15:41:12
boostを1.3.4にバージョンアップしたら
コンパイル・実行できました。
0517デフォルトの名無しさん2007/11/26(月) 23:15:38
すみません、くだらない質問なのですが
これまでマクロとか使ったことがなくて…教えてください。

#define IX(i,j) ((i)+(N+2)*(j))
と書かれていて
1次元の配列ポインタに x[IX(i,j)]
こう書かれていた場合、どこをアクセスしてるのでしょうか。

また
#define SWAP(x0,x) {float * tmp=x0;x0=x;x=tmp;}
これも意味がわかっていません。

おねがいします、助けてください
0518デフォルトの名無しさん2007/11/26(月) 23:21:23
>>517
落ち着いて展開すれば大丈夫。
x[ IX( i, j ) ]→x[ i + N + 2 * j ]
一次元配列を二次元配列のように扱う時に使ったりするかな?

SWAPのほうは単純に2つの値(float *)を入れ替えてるだけ。
SWAP( fp1, fp2 );とかけば
{ float * tmp = fp1; fp1 = fp2; fp2 = tmp; }
0519デフォルトの名無しさん2007/11/26(月) 23:34:20
ありがとうございます(;;
ものすごい優しく応えてくれて、なんかほんとに涙出てきました。

>一次元配列を二次元配列のように扱う時に使ったりするかな?
まさしくその通りです。
1次元配列の i+N+2*j ということですね。

{1 2 3 4
5 6 7 8
9 8 7 6
5 4 3 2} の場合 2段目の6にアクセスしたいとき N=4だから
IX(1,1) = 1+4+2*1 = 6 つまり、前から6番目の6にアクセスできますね!
ありがとうございます。。。ほんとようやくわかりました(;;

SWAPの方は、入る値は float * 型じゃないとダメ、ですよね?
これに1次元の配列ポインタが入ると、配列そのものが入れ替わる、ということですよね?

ほんと、、、わからなくて、悶々として、誰にも聞けなかったので
本当に助かりました。ありがとうございました(;;
0520デフォルトの名無しさん2007/11/27(火) 01:11:23
>>519
>これに1次元の配列ポインタが入ると、配列そのものが入れ替わる、ということですよね
単に変な文章になっているだけかもしれないけど、配列そのものが入れ替わるのではなく、
ポインタが指しているものが入れ替わるだけだよ。

int a[100], b[100];
int *p = a;
int *q = b;

SWAP(a, b); // コンパイルエラー
SWAP(p, q); // pがbを指し、qがaを指すようになる。a, bの実体は何も変わらない。
0521デフォルトの名無しさん2007/11/27(火) 14:42:13
最大で2000ほどの双方向リストがあるのですが
これを高速にソートするにはどういった方法があるのでしょうか?
頻繁にソートが呼び出されるのでバブルソートでいいものなのかどうなのか判断つきません
0522デフォルトの名無しさん2007/11/27(火) 14:51:15
マージソートとかクイックソートとか

頻繁の程度にもよるし、どの程度の遅さまで許容されるかにもよるし、
実際やってみて遅くなければ別にいいんじゃね?
0523デフォルトの名無しさん2007/11/27(火) 15:04:46
だからって、バブルソートなんか実装したら間抜けだけどな。
0524デフォルトの名無しさん2007/11/27(火) 15:11:55
頻繁にソートする必要があるのなら、常にソート済みの状態にしておくべき。
0525デフォルトの名無しさん2007/11/27(火) 16:36:22
マージソートでいってみようと思います
ありがとうございました
0526デフォルトの名無しさん2007/11/27(火) 18:19:50
普通に STL のソートじゃダメなの?
0527デフォルトの名無しさん2007/11/27(火) 21:00:21
Cなのかもしれないし、C++コンパイラは使えるけどSTLがないのかもしれない。
0528wolf ◆8VH3XAqjlU 2007/11/27(火) 22:09:04
>>521
>>525

**** may be something complicated *****

strategy pattern
http://home.earthlink.net/~huston2/dp/strategy.html
0529デフォルトの名無しさん2007/11/28(水) 00:48:43
mapのキーに構造体を利用してデータを格納しているのですが、
[]を使用した際に想定した動きをしてくれません。
下記がそのソースです。

#include <iostream>
#include <map>
#include <string>

// キー
struct StaffKey {
int section;
std::string code;
};
bool operator <(const StaffKey& lhs, const StaffKey& rhs) {
return lhs.section < rhs.section || lhs.code < rhs.code;
}
// データ
struct StaffData {
std::string name;
};
// キーとデータを紐付ける
typedef std::map<StaffKey, StaffData> StaffMap;

void insert(StaffMap& staffs, int sect, const char* cd, const char* nm) {
StaffKey key = {sect, cd};
StaffData& data = staffs[key];
data.name = nm;
}
05305292007/11/28(水) 00:49:27
int main() {

StaffMap staffs;
insert(staffs, 1, "ab123", "Taro");
insert(staffs, 2, "ab123", "Jiro");
insert(staffs, 1, "ab111", "Hanako");
insert(staffs, 1, "ab133", "Ken");

for (StaffMap::iterator it = staffs.begin(); it != staffs.end(); ++it) {
const StaffKey& key = it->first;
const StaffData& data = it->second;
std::cout << key.section << "," << key.code << ":" << data.name << std::endl;
}
std::cout << std::endl;
for (StaffMap::iterator it = staffs.begin(); it != staffs.end(); ++it) {
const StaffKey& key = it->first;
const StaffData& data = staffs[key];
std::cout << key.section << "," << key.code << ":" << data.name << std::endl;
}
}
05315292007/11/28(水) 00:50:28
----------------
実行結果
----------------
1,ab111:Hanako
1,ab123:Taro
1,ab133:Ken
2,ab123:Jiro

1,ab111:Hanako
1,ab123:Taro
1,ab133:
2,ab123:Jiro

はじめにイテレータを用いて全件のダンプを出力しています。
次に、[]を使ってデータを取得&出力しているのですが、
一部のデータのみ値が取得できない状態に陥っています(ab133:Kenのデータ)
独学で勉強しており他の人に聞くことが出来ないため、どこがおかしいのか全く判りません。
どうか助力をお願いします

長々とすみません。
なお、環境はLinux + GCC4.1.2です。
0532デフォルトの名無しさん2007/11/28(水) 00:53:27
>>531
allocator が無いからじゃないかな?(綴り怪しいけど)
0533デフォルトの名無しさん2007/11/28(水) 00:58:09
>>529
> bool operator <(const StaffKey& lhs, const StaffKey& rhs) {
> return lhs.section < rhs.section || lhs.code < rhs.code;
> }

これが順序付けになってないっぽい。
↓これでいいかな?

if (lhs.section < rhs.section) return true; else if (rhs.section < lhs.section) return false;
return lhs.code < rhs.code;
05345292007/11/28(水) 01:11:31
>>532
mapのテンプレート引数にstd::allocator<StaffKey> を追加してみましたが変わらずでした。
(見よう見まねに意味判らずやってます)

>>533
出来ました!!
||だとショートサーキットが有効になるので大丈夫だろうと思って深く考えていませんでしたが
やはり単純なミスだったんですね。。。

助かりました。どうもありがとうございました
0535デフォルトの名無しさん2007/11/28(水) 01:16:33
そもそも StaffKey::section の比較で両者とも同じだった(順序付けできなかった)場合に、
という仕様とは完全に異なるからな。
05365292007/11/28(水) 01:27:07
右辺値のsectionと左辺値のsectionが等しかった場合の考慮がされていなかった
ってことですよね?
だから正しく順序付けが出来ず、key指定時にデータの特定が出来なかった。
0537デフォルトの名無しさん2007/11/28(水) 02:17:08
a.i.u.e.oとかa->i->u->e->o(以下果てしなく続く)のような
ながーい構造体とかポインタの参照は
コンピュータ内部では一つ一つ計算してたぐり寄せているのでしょうか?
仮にそうだとして10万くらい続いているとしたら
終わりのx->y->z ←こいつのポインタを持っておけば無駄が省けるのでしょうか?
0538デフォルトの名無しさん2007/11/28(水) 02:19:17
省ける
持っておけるなら。
0539デフォルトの名無しさん2007/11/28(水) 02:25:03
>>538
やはりそうでしたか
これでまた一つ疑問が解けました
ありがとうございました
0540デフォルトの名無しさん2007/11/28(水) 04:46:32
a.b.cの形は、オフセット計算だけで、コンパイル時に確定してるから無意味だよ。
a->b->cは間接参照で、実行時に中身を追うから、bに相当するポインタをtmpとして持つ意味があるけど。

もちろんこれはC/C++の話で、
他言語だとCの->に相当する部分で.を使用するから別の話になるし
配列として宣言して、あえて->を使う場合なんかはあてはまらないけどね。
0541デフォルトの名無しさん2007/11/28(水) 09:31:45
一時的に特定のキーボードのキー入力を受け付けなくする方法か関数を教えてください
0542デフォルトの名無しさん2007/11/28(水) 10:02:24
我慢する
0543デフォルトの名無しさん2007/11/28(水) 10:07:21
キーボードクラッシャーにお願いする
天皇陛下万歳
0544デフォルトの名無しさん2007/11/28(水) 10:08:20
キーを外してしまうのは確かに有効だな
0545デフォルトの名無しさん2007/11/28(水) 10:40:10
ああ、おれもPOWERキーとかWINキーとかは外してるな。
0546デフォルトの名無しさん2007/11/28(水) 12:01:54
こんにちは.改行制限で見難くなっていますがどうかお許しください.

シリアルポートの開け方について質問させてください.
環境は…Windows XP SP2,Borland C++ Compiler 5.5,言語はC言語です.
この環境で下のコードをコンパイルしようとするのですが,
C:\borland\bcc55\Include\winuser.h 4804: 宣言が正しく終了していない
C:\borland\bcc55\Include\winuser.h 4811: 型名が必要
という二つのエラーがでて,コンパイルできません.
winuser.hの該当箇所は, typedef struct tagINPUT{…} の部分です.
いろいろいじってみたのですが,どうも見当がつきません.どこがおかしいのでしょうか.
下のコードは,
ttp://www.geocities.jp/terukat/_geo_contents_/win/comm.html
ttp://members.jcom.home.ne.jp/0434383301/vc10.htm
ttp://plaza.harmonix.ne.jp/~ahoshino/vb/CreateFile.htm
を参考にしました.

#include<windows.h>
int main(void){
HANDLE hComm = CreateFile(
"COM1",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
return 0;
}
0547デフォルトの名無しさん2007/11/28(水) 12:05:11
>>546
bccで他にWinAPIを呼ぶプログラムを書いたことは?
それがあるならそれを参考に見直してみればいい。
そうでないなら、そういうサンプルを探せばいい。
0548デフォルトの名無しさん2007/11/28(水) 12:20:06
>>541
Ctrl + Alt Dlt を無視したいとかそういうアプリではどうにもならない割り込みのあれかな?
0549デフォルトの名無しさん2007/11/28(水) 12:34:00
>>546
>bcc32 a
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
test.cpp:
警告 W8004 a.cpp 13: 'hComm' に代入した値は使われていない(関数 main() )
Turbo Incremental Link 5.66 Copyright (c) 1997-2002 Borland

BCB6だけどエラーが出ない

>>541
WindowsならCtrl+Alt+Deleteとかの特殊なの以外はキーフックで殺せる
05505462007/11/28(水) 12:42:20
>>547
ありがとうございます.
APIプログラミングの経験はないです.
C言語とAPIでシリアルポートにアクセスしているプログラムのソースは
見つかったんですが,どこが違うのかわかりません.
他に必要な処理があるのかと思ったんですが,
私の力ではそのプログラムのなかからそれを見つけることができませんでした….

>>549
ありがとうございます.
私も今TurboC++で試してみたんですが,
同じ警告しかでませんでした.
うーん.なんででしょう.
05515462007/11/28(水) 12:45:20
>>550に対する補記

Turbo C++ でならコンパイルできたということです.
0552デフォルトの名無しさん2007/11/28(水) 12:45:32
bcc55だと他にインクルードする必要があったりしてね。
0553デフォルトの名無しさん2007/11/28(水) 12:48:18
>>546
#include <windows.h> だけのソースもコンパイルできなかったりする?
05545462007/11/28(水) 12:51:48
>>552
550で書いているソースがインクルードしていたものを
一応すべてインクルードしてみたんですが,だめでした….

>>553
コンパイルできなかったです.
0555デフォルトの名無しさん2007/11/28(水) 12:58:35
>>554
bcc5.5.1で>>546のソースコンパイルできたよ
ファイルが壊れてるかもしれんから、再インストールしてみ
0556デフォルトの名無しさん2007/11/28(水) 12:58:37
>>554
そりゃなんかおかしいね
bcc再インストールしてみた方がいいかもしんない
05575462007/11/28(水) 13:20:32
再インストールをしてみたら,無事にコンパイルできました!
お騒がせしました.みなさん本当にありがとうございました!
0558デフォルトの名無しさん2007/11/28(水) 18:14:23
すいません、仮想関数とか継承とかで頭がこんがらがってきたので教えてください
仮想関数を含むオリジナルクラスを継承したクラスのインスタンスをnewしてそのポインタを
オリジナルクラスにキャストしてもう一度もとのクラスにキャストし直したもどした場合は
正常に動作するのですが、オリジナルクラスに仮想関数が含まれない場合はコンパイラエラーが出ます、
これは仮想関数を含むオリジナルクラスのインスタンスの場合だけそのクラスを継承したポインタにキャストできるということなのでしょうか?
この場合、オリジナルクラスのインスタンスには継承先の情報が無いと思うのですがどこから持ってきてるのでしょうか?

ついでにもうひとつお願いします
newでインスタンスを作成した場合deleteしなければ、プログラム終了まで有効なのでしょうか?
例えば関数の中でnewを行いクラスのポインタを変数に格納してそれを関数の引数として戻してnewを行った関数の外で使用しても
最後にdeleteさえすれば大丈夫なのでしょうか?

乱文失礼しましたが、よろしくお願いします。





0559デフォルトの名無しさん2007/11/28(水) 18:29:41
>仮想関数を含むオリジナルクラスのインスタンスの場合だけそのクラスを継承したポインタにキャストできる
dynamic_castの話なら、そのとおり。仮想関数を持たないクラスには働かない。
継承先の情報はインスタンスが隠し持ってる仮想関数テーブルに入ってる。
そもそもそれがなきゃ仮想関数の呼び先を解決できない。

deleteしなければプログラム終了まで有効。その続きのも大丈夫。
deleteし忘れてどんどんnewしてるとそのうちメモリを食い尽くすから要注意。
0560デフォルトの名無しさん2007/11/28(水) 18:54:52
>>559
回答、ありがとうございます。
これでやっと先にすすめそうです。
0561デフォルトの名無しさん2007/11/28(水) 18:59:42
最近deleteがdelegateに見えてしょうがないんだがもうダメなのか?
0562デフォルトの名無しさん2007/11/28(水) 19:04:58
だめだね。あの手の便利すぎる機能はプログラマの脳を破壊する。
0563デフォルトの名無しさん2007/11/28(水) 19:37:45
本物のプログラマは○○を使わない

【○○にはお好きな(またはお嫌いな)単語をお入れください】
0564デフォルトの名無しさん2007/11/28(水) 19:38:21
本物のプログラマはコンドームを使わない
0565デフォルトの名無しさん2007/11/28(水) 19:39:46
本物のプログラマは有給を使わない
0566デフォルトの名無しさん2007/11/28(水) 19:53:16
すいません、もうひとつお願いします。
関数内で仮想関数を含むオリジナルクラスを継承したクラスのインスタンスをnewでつくりそのポインタを
オリジナルクラスにキャストして関数の引数として返し、そのポインタをもう一度継承後のクラスにキャストした場合、
オリジナルクラスに存在しない継承後のクラスが持っているメンバ変数の値が維持されているのを確認できたのですが
この部分の値もずっと保持されるであってますか?
0567デフォルトの名無しさん2007/11/28(水) 20:03:54
- 本物のプログラマは有給を使わない
+ 本物のプログラマは有給を使えない
0568デフォルトの名無しさん2007/11/28(水) 20:11:30
>>563
そういうネタはマ板の方がいいんじゃね
0569デフォルトの名無しさん2007/11/28(水) 20:13:07
>>566
合ってる
ポインタをいくらキャストしてもインスタンスの実際のクラスが変わったりはしない
0570デフォルトの名無しさん2007/11/28(水) 20:31:14
>>569
回答、ありがとうございます
0571デフォルトの名無しさん2007/11/28(水) 20:36:46
本物のプログラマは言葉を使わない
0572デフォルトの名無しさん2007/11/28(水) 21:05:56
>>566
それはダウンキャストと言うのは知ってるね
dynamic_castは何をしようとするのかプログラマが知ってる限り
問題はない
0573デフォルトの名無しさん2007/11/28(水) 21:24:52
どうでもいいけど(いや、よくないけど)関数が返す物は引数じゃないんじゃね?
0574デフォルトの名無しさん2007/11/28(水) 23:00:01
3つほど質問させてください

・C++にはキャストがいくつかありますが、それぞれの役割がよく分かりません。詳説願います。

・inline関数についてですが、同一ソース中でないとinline展開されえないですか?

・演算子オーバーロードにおいて左オペランドに自作関数をとる演算子等を定義する場合、
通常のメンバ関数のような形式で定義するのと通常のグローバル関数のような形式で定義するのにはどのような違いがありますか?
bool Foo::operator +(Foo rhs)とbool operator +(Foo lhs,Foo rhs)みたいなののことです

よろしくお願いします
0575デフォルトの名無しさん2007/11/28(水) 23:09:03
>>574
http://www.google.co.jp/search?q=C%2B%2B+%E3%82%AD%E3%83%A3%E3%82%B9%E3%83%88
0576デフォルトの名無しさん2007/11/28(水) 23:31:54
>>574
オブジェクト間最適化機能のあるコンパイラなら、別のコンパイル単位にある関数でも
インライン展開され得る。
0577デフォルトの名無しさん2007/11/28(水) 23:41:11
■キャスト
詳説せず、厳密さも気にせず簡単にまとめるとこんな感じ。
・const の付け外し→const_cast
・標準変換、およびその逆変換→static_cast
・安全な downcast や crosscast→dynamic_cast
・A→B→Aで戻る以外は実装依存→reinterpret_cast

■inline
同一ソースって何?
規格上は基本的に同一翻訳単位に inline 関数の定義がないと駄目だし(ただし定義前に呼び出しがあってもOKと書いてあった)、翻訳単位間で定義が一致する必要がある。
最適化としての inline 化なら最近は >576 らしい。Exceptional C++ Style にもそんなことが書いてあった。

■演算子オーバーロード
×自作関数
○自作クラス
だとして、メンバ関数にすると第 1 引数がその自作クラスの場合に限定される。
例えば、Foo() + 1 はどちらでも実現可能だけど、 1 + Foo() はメンバ関数で実現することができない。
■ このスレッドは過去ログ倉庫に格納されています