C++相談室 part66at TECH
C++相談室 part66 - 暇つぶし2ch716:デフォルトの名無しさん
09/04/18 15:02:24
>>715
あ、公式っていうのはISOではなくJISのこと?
それはタダで見られる数少ない合法的なものだよ。
(ちなみにそのURLは検索結果のものだから他の人には見えないよ)
>>709の文章の書き方が悪いって言う話?
ちゃんとしていないものの例=非合法なコピー品
と書くべきだったかな?


717:デフォルトの名無しさん
09/04/18 15:04:58
>>706
初めからそう書けよ

718:デフォルトの名無しさん
09/04/18 15:05:44
おまえら釣られまくりだな。

719:デフォルトの名無しさん
09/04/18 15:08:12
>>716
>>708が言ってるのは、
>タダで見られる数少ない合法的なもの

>金を払わなければ見られないもの
の違いを教えて、ってことだと思うよ。

720:デフォルトの名無しさん
09/04/18 15:11:32
>※最新バージョン9の使用は今しばらくお待ちください。

おい。

721:デフォルトの名無しさん
09/04/18 15:12:14
久々に見に来たら何唾壺の有様は。
まったり進行していた時代はどこへ行った!

大人は黙ってまとめてあぼんだな。


722:デフォルトの名無しさん
09/04/18 15:13:20
セキュリティが厳しくなる前に保存しておいて正解だったな

723:デフォルトの名無しさん
09/04/18 16:45:31
static const volatile int x=42;
とかあったとするじゃん。
この前のC++における型名や修飾子の順番ってどう規定されている?
どんな順番が望ましいとか、どこまで好き勝手並べて良いとか。。。


724:デフォルトの名無しさん
09/04/18 16:54:59
この前っていつのことだよ。覚えてねーよ。

725:デフォルトの名無しさん
09/04/18 17:08:54
>>724
日本語おかしかったか。

static const volatile int x=42;
とかあったとするじゃん。
このように変数名の前につけるような
型名や修飾子の順番ってC++においてどう規定されている?
どんな順番が望ましいとか、どこまで好き勝手並べて良いとか。。。

726:デフォルトの名無しさん
09/04/18 17:25:35
const volatileって意味あるの?

727:デフォルトの名無しさん
09/04/18 17:28:18
>>726
ハードウェアが書き込み,プロセッサが読み出す領域: const volatile
ハードウェアが書き込み,プロセッサが読み書きする領域: volatile
プロセッサが書き込み,ハードウェアが読み出す領域: volatile

っていうのを見つけた。
[C,C++] const と volatile - bnez の日記
URLリンク(slashdot.jp)



728:デフォルトの名無しさん
09/04/18 17:41:23
>>725
別に決まりはないけど、まあみんな常識で考えて
記憶クラス指定子→cv修飾→型名の順番にしているね。
コンパイラを通すだけならint const volatile staticなんて並べても通る。

729:デフォルトの名無しさん
09/04/18 17:42:24
好みが現れるのはポインタ・参照の*と&の前後の空白の開け方、constとの順序だな。
int *p; int* q;とか。

const int* p2; int const* q2;
上のq2は、constなポインタへのconstで一貫性があるように見える。
const int* const p3; int const* const q3;

730:デフォルトの名無しさん
09/04/18 17:54:08
>>725
ストレージクラス(static) 型(int) cv修飾(const volatile) 識別子(x)

基本的にcvはその直前(左)にある型を修飾するけど、例外的にその左に型がない場合は直後の型を修飾する

規格では7.1あたりに書いてあるよ

731:デフォルトの名無しさん
09/04/18 18:10:15
一応誤解されないように言っとくと一番左の型の修飾子はその左に置くのが一般的だと思う
static const volatile int x でok

732:725
09/04/18 18:13:17
>>728-730
ほっほ~。
了解しました。
ありがとう。


733:デフォルトの名無しさん
09/04/18 18:40:53
質問です

struct fruit{
  int apple;
  int banana;
  void clear(){
    ZeroMemory(this, sizeof(*this));
  }
  int orange;
};

この構造体をローカル変数に定義した場合、メモリ見るとそれぞれの
3つの値がスタックに順に並びました。
clear を呼ぶと、確かに apple, banana, orange が
クリアされます。
ZeroMemory で this を渡していますが、clear() は含まれていないようです。

この構造体の場合、fruit.clear() は main() と同じように、
code セグメントに配置されるんでしょうか。
class も同じ考え方になるのでしょうか。

734:デフォルトの名無しさん
09/04/18 18:42:50
>>733
当然、そうしないといけないという決まりはないが、
自然に実装すればだいたいそんな感じになる。classでも同じ。

735:デフォルトの名無しさん
09/04/18 19:49:59
>>731
コンパイラーによっては前付きは古いって怒られることあるよ。
ここらへんに増築の限界感を感じる・・・

736:デフォルトの名無しさん
09/04/18 21:56:22
1) const int *p;
2) int const *p;
3) int *const p;

1と2がpointer to const intで、3はconst pointer to intであってますよね?

737:デフォルトの名無しさん
09/04/18 21:57:06
>>736
あってる。

738:デフォルトの名無しさん
09/04/18 21:57:16
あってます。

739:デフォルトの名無しさん
09/04/18 21:59:07
declarator としての const は常に * const の形で現れる。
っていうか、構文解析法は頭に叩き込みましょう^^

740:デフォルトの名無しさん
09/04/18 22:00:58
派生クラスのメンバ関数foo()が例えprivateでも、
基底クラスで同じメンバ関数foo()がvirtualと指定されていれば
基底クラスのポインタを介した場合のみ呼び出せるのか。

実際やってみるとうまくいくんだが、別におかしくはないよね?
class Base
{
public:
virtual void foo(){std::cout << "Base foo!" << std::endl;};
Base(){std::cout << "Base Constructor!" << std::endl;};
virtual ~Base(){std::cout << "Base Destructor!" << std::endl;};
};

class Derived : public Base
{
void foo(){std::cout << "Derived foo!" << std::endl;};
public:
Derived(){std::cout << "Derived Constructor!" << std::endl;};
virtual ~Derived(){std::cout << "Derived Destructor!" << std::endl;};
};
void foo()
{
Base* pbd(new Derived);
pbd->foo();
delete pbd;
}


741:デフォルトの名無しさん
09/04/18 22:07:06
>基底クラスのポインタを介した場合のみ呼び出せるのか。

派生クラス(Derived)のポインタを介した場合でも呼び出せるでしょ?


742:デフォルトの名無しさん
09/04/18 22:08:11
おかしくないよ。
もし呼び出せなくなったりするのなら
ポリシークラスとか存在価値なくなっちゃうし。

743:デフォルトの名無しさん
09/04/18 22:08:22
>>741
コンパイルエラーになったよ。

744:デフォルトの名無しさん
09/04/18 22:09:53
自分のメンバ関数なのに?

745:デフォルトの名無しさん
09/04/18 22:11:16
privateにしたら呼び出せなくなるのは当たり前だろ

746:740
09/04/18 22:11:19
>>741
error: `virtual void Derived::foo()' is private
って言われますね。
>>744
「自分のメンバ関数から」ならprivateメンバ関数も呼出せるけどね。

747:740
09/04/18 22:19:08
あと、基底クラスのデストラクタがprotected指定されていても、
派生クラスのデストラクタがpublic指定されていれば
boost::shared_ptrを使った場合なら呼出せるのね。

必要条件:
基底クラスのデストラクタがprivateでないこと。
また、派生クラスのデストラクタがpublicであること。
さらに生のポインタじゃダメなようだ。


748:740
09/04/18 22:20:08

class Base
{
protected:
virtual ~Base(){std::cout << "Base Destructor!" << std::endl;};
public:
virtual void foo(){std::cout << "Base foo!" << std::endl;};
Base(){std::cout << "Base Constructor!" << std::endl;};
};

class Derived : public Base
{
virtual void foo(){std::cout << "Derived foo!" << std::endl;};
public:
Derived(){std::cout << "Derived Constructor!" << std::endl;};
virtual ~Derived(){std::cout << "Derived Destructor!" << std::endl;};
};
void foo()
{
boost::shared_ptr<Base> pbd(new Derived);
pbd->foo();
}

しかもboost::shared_ptrの動的削除子のおかげでデストラクタにvirtualすら付けなくてもいけるのか。


749:デフォルトの名無しさん
09/04/19 00:39:35
>748 >454

750:デフォルトの名無しさん
09/04/19 11:55:04
>>727
>ハードウェアが書き込み,プロセッサが読み出す領域: const volatile
この使い方って本当に大丈夫?
例示できないけどconst有り無しのオーバーロード関数とか・・・


751:デフォルトの名無しさん
09/04/19 12:10:18
>プロセッサが書き込み,ハードウェアが読み出す領域: volatile

これも疑問だよな

プロセッサもハードウェアも読み書きする領域じゃないのか?

752:デフォルトの名無しさん
09/04/19 12:16:38
そのコードが動作するプロセッサの管理外で読み書きされる領域

753:デフォルトの名無しさん
09/04/19 13:47:07
プロセッサによって細かい挙動は違うだろうけど、
volatileって常に最新の実体を参照するようにするだけだよね?

754:デフォルトの名無しさん
09/04/19 13:52:46
最適化を無効にしてるだけだから

755:デフォルトの名無しさん
09/04/19 14:38:46
その変数を扱っているプログラムとは別のなにかによって内容が変更されうる変数。
volatile int i;
int j;
if ( i == 1 ) j = i;
で j == 1 でないときがありえる変数。

constをつけるとそのプログラムからは内容が変更できないのに参照するたびに内容はかわるかもしれない変数になる。

ポインタ経由でアドレスにマッピングされたI/Oポートとやり取りするのに使ったりする。



756:733
09/04/19 14:51:18
>>734
thx! 亀レススマソ

「自然に実装すれば」というのは、アセンブル段階で
構造体やクラスのコードはすべて code セグメントに集約している
場合、ということでしょうか。

もう1つ謎なのは、インスタンス化を可能とするために、
clear() を呼んだ際に、どのメモリ領域が this に該当するのかを
どうにかして渡しているはずですが、その文献が見当たりません。
どのように処理しているんでしょうか。

757:デフォルトの名無しさん
09/04/19 16:36:28
>>756
> 「自然に実装すれば」というのは、アセンブル段階で
> 構造体やクラスのコードはすべて code セグメントに集約している
> 場合、ということでしょうか。

クラス(あるいは構造体)のメンバ変数は、
インスタンス毎に値が違うので、各インスタンスごとに
用意してやる必要があるが、メンバ関数は各クラス毎に
一つだけ用意してやればよい。
よって、>>733の場合だと、スタックにメンバ関数(へのポインタ)が
用意される必要はない(virtual関数は微妙に別)


> もう1つ謎なのは、インスタンス化を可能とするために、
> clear() を呼んだ際に、どのメモリ領域が this に該当するのかを
> どうにかして渡しているはずですが、

>>733の例のclear()の場合、処理系が勝手に

__struct_fruit_clear(fruit* this)

のような関数に置き換える(ことが多い)。ただし、処理系依存。

758:733
09/04/19 17:46:48
>>757
丁寧な説明、本当にありがとうございます。
かなり理解できました。

759:デフォルトの名無しさん
09/04/19 20:32:45
個人開発にて C++ にインターフェースの概念を取り入れようとしております。
.NET や Java では interface が言語仕様として存在しますが、
C++ では言語仕様レベルで Java のような interface は存在しません。
なので、単一継承とは別に、
純粋仮想関数だけで固められたクラスのみ、多重継承を許可して実装しようと思ってます。
そのような実装で問題点などありますでしょうか。
よろしくお願いします。

760:デフォルトの名無しさん
09/04/19 20:35:38
特に問題はないと思うけど、インターフェイスだと分かるようなクラス名にするとか工夫した方がいいかも
結局は規約次第だと思うが

761:デフォルトの名無しさん
09/04/19 20:59:23
>>760
レスありがとうございます。
やっぱり規約や、実装者の意識の問題になりそうですよね。
個人(自分だけ)での開発なので、その辺の問題は薄そうですが・・・
コンパイラで上手くカスタマイズして、
間違った実装したときに警告とか出せればいいんですけどね。

762:デフォルトの名無しさん
09/04/19 21:03:35
>>759
struct IHoge {virtual ~IHoge();};
struct IFoo : IHoge {};
struct IBar : IHoge {};

class Piyo : IFoo, IBar {};
Piyo piyo;
このとき、(IHoge*)(IFoo*)&piyo == (IHoge*)(IBar*)&piyoが
真になるとは限らないということを許容できないなら、仮想継承を使うべきと言っておく。

処理系間や多言語間での互換性を高めるため、仮想継承を使っていないMSのCOMでは、
これが理由でポインタの比較が面倒(仮想継承の代わりに規約で縛りを入れて対処している)。

763:デフォルトの名無しさん
09/04/19 21:45:10
>>762
operatorの再定義のことを言ってる?
よく分からん。

764:デフォルトの名無しさん
09/04/19 22:00:25
>>763
仮想継承しなければ、IFooの部分オブジェクトのIHogeとIBarの部分オブジェクトのIHogeは別物ということ。

インタフェースという元のお題からは外れるが、IHogeに非静的メンバ変数xがあれば、
IFoo側のxとIBar側のxは、仮想継承しないなら別々、仮想継承したら同一の存在だろ。
(かなり乱暴な言い方だけど)
それと同じ話。単にメンバ変数がないからポインタの比較でもしないと問題が発覚しないだけで。

765:デフォルトの名無しさん
09/04/19 22:20:17
教科書に書いてある内容なんだから
「仮想継承」も調べておいた方がいいとかで済ませればいいのに

766:デフォルトの名無しさん
09/04/19 23:49:51
>>762
レスありがとうございます。
仮想継承はよく理解してなかったんで、Wikipedia とかで調べてました。
多重継承する上で理解しておかないといけない概念ですね。
ありがとうございました。

767:デフォルトの名無しさん
09/04/19 23:52:40
おまえらスレがもったいないから
>>765さんが教科書で覚えたことはいちいち説明するなよ。
ググレカス。

768:デフォルトの名無しさん
09/04/19 23:56:49
俺もC|Java|C#|VB厨だから仮想継承を調べてみた
たしかにこれはググればわかる気がする
今後は namespace C++{ 仮想継承 } とか名前空間で囲んでくれると名前的にわかりやすい
RDFでも可

769:デフォルトの名無しさん
09/04/20 13:17:27
namespaceは神
これさえあればC言語風に書けるしなw
クラス?
そんなもんいらね。

770:デフォルトの名無しさん
09/04/20 13:26:09
namespaceはCに取り込まれるべきだと思うね
コメントの//より優先されるべきだった

771:デフォルトの名無しさん
09/04/20 14:31:19
namespaceだとC++と同じだから、namekukanでCに取り込んだら
どうだろうか

772:デフォルトの名無しさん
09/04/20 14:33:16
programminglang::C::namespaceでいいよ。

773:デフォルトの名無しさん
09/04/20 15:40:24
namespace 入れてくれれば enum を気兼ねなく使えるしな

namespaceだとC++と同じだから、miniascapeでCに取り込んだらどうだろうか

774:デフォルトの名無しさん
09/04/20 19:37:14
普通に
namespaceでいいよ。だからさっさと取り込んでくれ。

775:デフォルトの名無しさん
09/04/20 22:17:27
namespiceでいいよ

776:デフォルトの名無しさん
09/04/20 22:20:40
namaespaceでいいよ

777:デフォルトの名無しさん
09/04/20 23:33:28
namaekukanだろjk

778:デフォルトの名無しさん
09/04/20 23:35:43
無名名前空間も頼む。
staticいちいち付けるの面倒なんじゃ。


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch