トップページtech
715コメント230KB

【C++】 const だけでメシが3杯食えちゃうスレ

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
C++で多用される const について疑問、質問、語り等なんでも書き込んでくれ。
0153デフォルトの名無しさんNGNG
>>151
ああ、ほんとだ、試してみたらVC7.1だと出来るのね。
知らなかった。
仕事上、特殊なSDKを使ってるので、未だにVC6がメインなので。

うーん、enumハックはtemplateでもよく使う
手法なんで知ってますが、組んでるプログラムの
関係上、どちらかというとfloat定数が欲しい場合が
多いので。

>>152
スコープ外れると知りつつも、スコープあまり関係ない定数の場合は
打鍵数の少ない方を取ってしまうダメ人間。
もちろんほんとにスコープで分けたい場合はメンバにしてますけど。
0154デフォルトの名無しさんNGNG
>>151の機能は標準化したの比較的最近だよな、そういえば。
確かに環境によっては使えないわ。
floatの定数欲しいときには困るんだよな…。
0155デフォルトの名無しさんNGNG
const_cast 最強
0156デフォルトの名無しさんNGNG
>>154
VC6以外のコンパイラは昔からほとんどできた
ただVC6の勢力が大きかっただけで。
まるでリトルエンディアンのアーキテクチャと
ビッグエンディアンのアーキテクチャみたい。
0157デフォルトの名無しさんNGNG
ところでモマイら、関数引数にconst付けますか?
int func(const int arg1, double *const arg2) {...
みたいな感じで。
0158デフォルトの名無しさんNGNG
つけるよー。
つけまくり。
ソースとデステネーション区別する意味でも、参照しかしない引数は
基本型以外ぜーんぶconstつけ。

…みんなそうだよね?
0159デフォルトの名無しさんNGNG
>>157
const int は意味がないので使わないが
const int& は使う。
0160157NGNG
>>159
const int &を使うのは常識として、const intを使うかどうか聞きたかったんだが…
つまり、>>147の例でconstをつけるなら、
関数引数にも(誤って代入しないように)constをつけるのもいいかな、と思うんだけど。
0161デフォルトの名無しさんNGNG
>>160
関数引数に代入云々は、呼び出し側には全く関係ないからなあ。
呼び出し側から見てどうでもいいものをプロトタイプに反映させるのは
個人的にはあまり好きくない。
0162デフォルトの名無しさんNGNG
>>161
必ずしもプロトタイプに反映させなきゃならんわけでもないぞ。
>>157の例なら、
int func(int arg1, double *arg2);
と宣言しておいて、定義側では>>157のようにすれば良い。

inlineやtemplateなんかには使えんがな。
0163デフォルトの名無しさんNGNG
宣言と定義が食い違うのは気持ち悪くないか?
0164デフォルトの名無しさんNGNG
気持ち悪い悪くない以前の問題で、定義と宣言の関係が崩壊してるんじゃないかと小一時間
ていうか、それって普通にコンパイラに怒られないのか?
0165デフォルトの名無しさんNGNG
>>164
それは無問題。
試してみろよ。
0166デフォルトの名無しさんNGNG
試してみろじゃなくて、規格で保証されているのか?
どっちにしろ、俺も気持ち悪くて使う気にはならんが。
0167デフォルトの名無しさんNGNG
いくらプロトタイプ宣言がコンパイラのためのものとはいえ
通ればいいってもんじゃ無い気が…


ていうか、本当に通るの?
マジで??

なんか今まで信じてたものが崩壊してく感じなんですが。
0168デフォルトの名無しさんNGNG
次世代言語EC++ではmutableは廃止されます。

http://www.caravan.net/ec2plus_j/language_spec.html
0169デフォルトの名無しさんNGNG
通る。規格でも合法。
0170デフォルトの名無しさんNGNG
>>169
規格の話するならできれば引用して欲しい。

>8.3.5 Functions 3
>(略)
> Any cv-qualifier modifying a parameter type is deleted.
> [Example: the type void(*)(const int) becomes void(*)(int) - end example]
> Such cv-qualifiers affect only the definition of the parameter within the body of the function;
> they do not affect the function type.

というわけで完全に合法だな。
でも個人的には宣言と定義で見た目が変わるのは気持ち悪いし、引数が const int なのも
気持ち悪いと思う。
0171デフォルトの名無しさんNGNG
あー、確かにそうだわ。
引数の上の const の有無では、関数のオーバーロードは成立しねえんだ。
関数プロトタイプの引数上 const の有無からじゃ、呼び出し側がどの関数呼べばいいのか
コンパイラは判別つけられないから、こりゃ当然の仕様なのか。

かといって、プロトタイプと実関数の定義が分かれてしまってて許されるなんて…。
気持ち悪いよ〜!!
0172デフォルトの名無しさんNGNG
>>158
> 参照しかしない引数は
> 基本型以外ぜーんぶconstつけ。
ポインタで渡したり参照で渡したり以外という意味でつか?
0173デフォルトの名無しさんNGNG
>>168
mutable指定子
例外処理
実行時型識別
ネームスペース
テンプレート
多重継承と仮想継承

mutable以外は外しちゃならない機能ばかり。
組み込みC++って大変ね。
0174デフォルトの名無しさんNGNG
例外ダメなのか…

RTTIはまあいいとして…

namespaceもなんとか大目に見られるとして…

テンプレートはコンパイラ側の問題だろうに…
上でも誰かが言ってたが、インラインアセンブラとの相性いいんだぞ…

多重継承はまあいらんとしても、仮想継承禁止ってなんだそりゃ…



C++なのか、それ。
C99と何が違うんだ。
0175デフォルトの名無しさんNGNG
多重継承を使わないなら、仮想継承も要らないんでないの?
0176デフォルトの名無しさんNGNG
>>175
C++使いも最近は実装の多重継承しないのが本流になっているので、
>>174がインターフェイスクラスの継承も機能的には多重継承だと気づかなかったに
8086ガバス
0177174NGNG
>>176
R4300ガバス進呈。
近所のTSUTAYAでGBAと交換できまつよー。



鬱山車納。
0178デフォルトの名無しさんNGNG
組み込みC++でうんざりするのはstdネームスペースがないことだよ。
ま、標準ライブラリも無いに等しいくらい少ないのだが。

なまけものコンパイラ屋が考えたのだと思ってる。
0179デフォルトの名無しさんNGNG
>>178
stdネームスペースが無い…マジスカ?
標準ライブラリも無いに等しい…マジスカ?

規格として存在する意義がよくわからん…。
とりあえず最底辺だけ決めたってことなんだろうか。
0180デフォルトの名無しさんNGNG
>>179
>規格として存在する意義がよくわからん…。
禿道。

規格を作ってポータビリティを向上できるようなシステムはリソースもあるので普通のC++でいいと思うし、
リソース的に色々制約があるシステムの場合はターゲットごとに癖が強いから規格にする意味がないし。
0181デフォルトの名無しさんNGNG
javaにもconstがほしい。
void fund(const Object &obj) const;
のconst ね

行って帰ってきたら、中身がかわってるかどうか、
わかんないなんて...
0182デフォルトの名無しさんNGNG
読み込み専用の(ゲッターだけの)インタフェースを実装し、
そのインスタンスを渡すようにしてはいかがだろう。


&って?
0183デフォルトの名無しさんNGNG
>>182が言った様なアプローチを基本にするために、constを
取っ払ってるのが最近の流行なんだろうけど…。

そのために一々細かくクラス用意するのはバカらしく思えることだってあるし、
J2MEとかだと、そもそもそんなことのためにクラス用意してる余裕は無かったりするんだよな。

基本型の配列渡すのにも、一々どっちがsourceでどっちがdestinationか確認しながらやるのはビクビクもんだ。
コンパイラにちょっと叱ってもらうだけでも、ヒューマンエラーは随分減るのに…。
0184遅レスNGNG
>>16
foo()はメンバ変数を変更しないという意味だろ?
0185デフォルトの名無しさんNGNG
getter で、変更されてもいい値を返すってことは、
clone なり new なりが発生するってことだろ。

clone と new が早けりゃ文句ないんだよ。
java は clone と new が遅いだろ。
0186デフォルトの名無しさんNGNG
constってC言語に属する低級なもので、本物のOOP言語には必要ないんだと思う。
0187デフォルトの名無しさんNGNG
「本物」ねぇ・・・
0188デフォルトの名無しさんNGNG
本物のオブジェクト指向言語は、型の変更不能性をインターフェイスで表明する。

public void change(Object argObject) { /* ... */ }
public void unchange(ConstObject argConstObject) { /* ... */ }

さらに、引数への代入をコンパイルエラーとして報告してもらいたければ、

public void unchange(final ConstObject argConstObject) { /* ... */ }

を使う。
0189デフォルトの名無しさんNGNG
関数オーバーロードでまとめてしまうと、OOPもへったくれもないってことなのか

道理だが…
まったく使う気しねえなあ…
0190デフォルトの名無しさんNGNG
理想と現実の間には深い溝がある.
0191デフォルトの名無しさんNGNG
>>188
class ConstBase {}
class MutableBase extends ConstBase {}
class ConstSub extends ConstBase {}
class MutableSub extends *** {}

*** はどうするのよ?
0192デフォルトの名無しさんNGNG
>>191
多重継承の呪縛に囚われた人間がここにも……!?








その腐った設計を見直せ
0193デフォルトの名無しさんNGNG
いや、だから const は継承では賄えないと言いたかったんだが。
0194デフォルトの名無しさんNGNG
>>192
はずかしい
0195デフォルトの名無しさんNGNG
>>192
えっち。
0196デフォルトの名無しさんNGNG
>>192
Java厨ウザイ
0197デフォルトの名無しさんNGNG
>>192
ちんこ洗ったか?
0198sNGNG
突き詰めて逝くとHaskellやCleanとかの副作用のない関数型言語を使えばいい,と思うに至った.
勉強中.

0199デフォルトの名無しさんNGNG
やっぱmainはこーだよな

int main(const int argc, const char* const* const argv)
0200デフォルトの名無しさんNGNG
やーめーれー
0201デフォルトの名無しさんNGNG
コンパイラにチェックしてほしいだけとちゃうんかと、小一時間(ry
0202デフォルトの名無しさんNGNG
引数自体のconstは好きにしてくれって気がするな。
有体に言うとウザい。
0203デフォルトの名無しさんNGNG
>>199
コーヒーこぼしちまったじゃねーかw!!
0204デフォルトの名無しさんNGNG
>199
だな
0205デフォルトの名無しさんNGNG
これはできんのだな
int main(int argc, char **argv) {
{
const int argc = argc;
const char*const*const argv = argv;
return 0;
}
}
0206デフォルトの名無しさんNGNG
199も厳密には規格違反のような希ガス
0207デフォルトの名無しさんNGNG
const int main(const int argc, const char* const* const argv) const
0208デフォルトの名無しさんNGNG
mainにthisがあると、君は!
0209デフォルトの名無しさんNGNG
void func (void) const { ... }
          ↑このconstってCで合法だっけ?
0210デフォルトの名無しさんNGNG
非合法。
すなわち危険な匂いを漂わせる船の男にして、港の女はメロメロ。
0211デフォルトの名無しさんNGNG
>>209
メンバ関数以外にも使える処理系があるのか?
0212デフォルトの名無しさんNGNG
心配するな。ずっとconstさ
0213デフォルトの名無しさんNGNG
>>209コレさえあれば合法(脱法?)
#define const
0214デフォルトの名無しさんNGNG
エリオット・ネスが
#ifdef const
#error 通報されますた!
#endif
を主要ヘッダに仕掛けてましたよ!
奴は一人でもやる気です!
0215デフォルトの名無しさんNGNG
>>214
#include <hoge>//など
#define const

マジレスするとヘッダのインクルードより後にやればいいだけでは?
0216デフォルトの名無しさんNGNG
>>215
自分の家族を守れば十分なんだろう?
0217デフォルトの名無しさんNGNG
相互リンク。
http://pc5.2ch.net/test/read.cgi/tech/1082047479/972-
0218デフォルトの名無しさんNGNG
ポインタにconst忘れる奴多杉なので、
願わくば、後ろにconst置くスタイルが一般的になって欲しい。
0219デフォルトの名無しさんNGNG
C++相談室の次スレはここですか?
0220デフォルトの名無しさんNGNG
>>209
亀レスだがfunc 後のfuncはクラスのメンバ関数にのみ許される。
一般の関数については許されてないし、必要ない。
0221デフォルトの名無しさんNGNG
func の後のfunc 罰
func の後のconst 丸
0222v(^・^)vNGNG
C++相談室の次スレはこちらです。
http://pc5.2ch.net/test/read.cgi/tech/1084030770/
0223デフォルトの名無しさんNGNG
Java/C#の仕様を見るといかにC++のconstが馬鹿げたものかがよくわかる。
0224デフォルトの名無しさんNGNG
単にあちらさんの教義に染まっただけでしょう。
0225デフォルトの名無しさんNGNG
IBMは何でreadonlyのままにしなかったんだろう
readonlyの方がわかりやすかった気も
0226デフォルトの名無しさんNGNG
素人なんですけど、
constが、ある変数を誤って変更しないようにする目的であるのなら、
constとして扱いたい変数の名称を、コンストっぽいやつ、
例えば、GravitationConstantとか、a_constとかにすれば良いの
ではないでしょうか。
0227デフォルトの名無しさんNGNG
  ハハハ
  ∧_∧  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 ( ^∀^)<  あほか
 ( つ ⊂ ) \_________
  .)  ) )
 (__)_)

0228デフォルトの名無しさんNGNG
>>226
そこでconst_castですよ
0229デフォルトの名無しさんNGNG
よーしパパ文字列リテラル書き換えちゃうぞー
0230デフォルトの名無しさんNGNG
素人なんですけど、
privateが、あるメンバ変数を隠蔽する目的であるのなら、
privateとして扱いたいメンバ変数の名称を、privateっぽいやつ、
例えば、private_dataとか、a_privateとかにすれば良いの
ではないでしょうか。
0231デフォルトの名無しさんNGNG
そこで #define private public ですよ
0232デフォルトの名無しさんNGNG
>>230
「おい。おまえの作ったクラス、うまく動かないぞ。このprivate_aって変数に0を代入したらおかしくなったぞ。」
と言われないためです。
0233デフォルトの名無しさんNGNG
#define 最強!!!
0234デフォルトの名無しさんNGNG
>>233
bcc
エラー E2153 233.cpp 1: #define 疑似命令には識別子が必要

g++
233.cpp:1:9: macro names must be identifiers

vc
233.cpp(1) : error C3209: '?III' : Unicode 識別子は現在サポートされていません。

mwcc
# File: 233.cpp
# -------------------
# 1: #define I I I
# Error: ^
# identifier expected
0235デフォルトの名無しさんNGNG
ところでWinMainのLPSTR lpszCmdLine
これLPCSTRにするとうまくいかなかったがconst LPSTRだとうまくいった。
typedef CHAR *LPSTR, *PSTR;
typedef const CHAR *LPCSTR, *PCSTR;
だと言うのに。

ところでwindows.hの中の中ではchar*やwchar*から大きく分けて、
〜CHAR/〜CH/〜STRの3種類にtypedefしてるけど、
〜CH系って使っているの見たことない。
0236デフォルトの名無しさんNGNG
const LPSTR = char * const
0237235NGNG
>>236
なぬっ!
そういうことだったのか。

winbase.hの中のWinMainの宣言をLPCSTRに書き換えれば、
もちろんうまくいくんだけどそこまでするメリットってないよね。
0238デフォルトの名無しさんNGNG
>>237
「うまくいく」「うまくいかない」が何なのかさっぱりわからない。
0239デフォルトの名無しさんNGNG
>237
何で無理やり const つけるのよ。
もともとついてないんだから変更しても構わないってことでしょ。
自分で変更しないってことを強制したいなら LPCSTR を受ける MyWinMain でも作って
WinMain から呼び出せばどーよ?
0240デフォルトの名無しさんNGNG
いたるところにconstをちりばめておけば、「うぬぅ!こいつ出来るな!」と思われるので使いまくってます。
0241デフォルトの名無しさんNGNG
つか、いたるところにconstをちりばめておかないと、「うぬぅ!漏れはここで何をやらかしたんだ!」という思いをしてしまうので使いまくってます。

あれですよ。
ドミノあほほど並べる人が途中に挟むストッパーみたいなもん。
0242デフォルトの名無しさんNGNG
>>241
うぬぅ!解り易い説明だぁ!
0243デフォルトの名無しさんNGNG
>>241
なるほど、どじな同僚に倒されないように、ですな。
0244デフォルトの名無しさんNGNG
>>243
自分で蹴っ倒す事もあるでよ。

まあそのなんだ。
倒さないことが大事なんであって、誰が倒すかは、この際問題じゃないですよ。
0245デフォルトの名無しさんNGNG
>>241
うまい!確かにそんな感じ。
0246デフォルトの名無しさんNGNG
他人の書いたクソ長い関数で
ローカル変数にconstがまったくないとすげえ不安になる

そういうときは、初めて代入するところに宣言をもってって
constにするといろいろ分かってくる。
0247デフォルトの名無しさんNGNG
>>246
コンパイラに「洗い出し」をやらせるんだよな。
漏れも泥臭い仕事の時にはよくやる(w
0248デフォルトの名無しさんNGNG
>>247
Yes. コンパイラは検出ツールでもあると考えているよ。
正直そういうアドバイス機能もあってもいいと思うんだよな。
どうせコンパイラは変数の有効期間を検出してるんだし。

で、
たまに見かけるのが、ループ変数のような一時変数を、関数の先頭で
宣言し、使いまわしている奴。Cのスタイルを引きずってるのかなあ。
明らかにconstractに時間のかかりそうなものなら分からんでもないが、
forループのiが置いてあると書いた奴の能力を疑う。

constからズレたけどオカズっつうことで
0249デフォルトの名無しさんNGNG
>>248
使いまわしの極意は、整数変数にポインタを代入することです。
Cのスタイルを引き摺っているんだろうけど、許せん。
0250デフォルトの名無しさんNGNG
>>249
古くからのプログラマで組み込み畑の人だと、void * の代わりに unsigned int を使ったりするから油断できない。
0251デフォルトの名無しさんNGNG
>>248
>ループ変数のような一時変数を、関数の先頭で

VC++あたりはデフォルトでそれを許してくれないのが…。
0252デフォルトの名無しさんNGNG
>>251
for (int i = ...)
 ...;
for (int i = ...)
 ...;
って書き方ができないことを言ってる? だったらVC.NETにすれば大丈夫。
そうでなくても、大抵の場合は二度目(以降)のintを省略するだけでも違うと思う。
■ このスレッドは過去ログ倉庫に格納されています