C++相談室 part66at TECH
C++相談室 part66 - 暇つぶし2ch423:デフォルトの名無しさん
09/04/05 18:03:11
デストラクタはpublicで宣言するものだよね?

privateで宣言すると、
まあ普通にコンパイルエラーになるんだけど、
特殊な状況でprivateなデストラクタってある?

なんか俺の知らないイディオムでありそうな気がしてきたんだが。


424:デフォルトの名無しさん
09/04/05 18:16:00
deleteをオーバーロードしてるとかじゃないとコンパイルすら通らなくね?

425:423
09/04/05 18:18:06
>>424
そう、通らない。

でも例によってC++は深遠だからさ、
俺が知らないだけで便利なイディオムがあったりするかな~って興味が出てきた。


426:デフォルトの名無しさん
09/04/05 18:21:59
とりあえずnewで生成してみろよ

427:デフォルトの名無しさん
09/04/05 18:22:20
自動変数や静的変数としては使えないが、newすることは出来る。
deleteはクラスのメンバ関数から出来る。
だから、使えないことはない。具体的にどう役立つのかは分からんが。

428:423
09/04/05 18:25:28
あ~、newで作るのか。
なるほどね。


429:デフォルトの名無しさん
09/04/05 18:26:30
Effective C++にて

const char* const authorName="ScottMeyers";//方式1
const std::string authorName="ScottMeyers";//方式2

この2つが紹介されていたんだけど、結局どっちが良いの?
本によれば方式2の方が良いよ的な書き方されていたんだけど、どうして方式2が良いのか分からない。



430:デフォルトの名無しさん
09/04/05 18:35:41
class MyClass{};
として、
boost::shared_ptr<MyClass> p(new MyClass);
だと大丈夫なのに
boost::shared_ptr<MyClass> p=new MyClass;
だとダメなのは何故でしょうか?

私は宣言時に
(初期化値)とするのと
=初期化値とするのは
等価にコンストラクタを呼び出す物だと思っていたので驚きました。


431:デフォルトの名無しさん
09/04/05 18:38:14
>>430
boost::shared_ptr<MyClass> p=boost::shared_ptr<MyClass>(new MyClass);


432:デフォルトの名無しさん
09/04/05 18:41:49
>>430
コンストラクタに explicit がついていると
> boost::shared_ptr<MyClass> p=new MyClass;
は不可能になる。

例えば
class MyClassA {
 MyClassA(int n);
};
class MyClassB {
 explicit MyClassB(int n);
};
となっていた場合、
MyClassA a(3); // OK
MyClassA a = 3; // OK
MyClassB b(3); // OK
MyClassB b = 3; // NG
となる。

また、
void myFuncA(MyClassA a);
void myFuncB(MyClassB b);
という関数があった場合
myFuncA(3); // OK
myFuncB(3); // NG
となる。myFuncB(MyClassB(3)) は可能。

433:デフォルトの名無しさん
09/04/05 18:42:16
>>431
それはキャストですよね。
つまりキャストしないとダメなんでしょうか?
なぜですか?


…あ、もしかして
boost::shared_ptr<MyClass>のコンストラクタが
explicitになっているということでしょうか?


434:433
09/04/05 18:43:20
>>432
すみません。
再読込してませんでした(> <)
失礼致しました。

explicitですね。
もうちょっと勉強して出直してきます。

435:デフォルトの名無しさん
09/04/05 18:44:05
>>430
スレリンク(tech板:106-109番)

436:432
09/04/05 18:44:11
ごめん、>>432の例だとコンストラクタがprivateになってるね。public: を付け足して読んでほしい。

437:433
09/04/05 18:51:15
>>435-436
ありがとうございます。
>newしたらすぐにスマートポインタにセットさせるのが基本。
これがRAIIってやつでしょうか?

438:デフォルトの名無しさん
09/04/05 18:52:46
>>423
カスタムデリータを使うときにデストラクタをprivateにして隠して、カスタムデリータ外から勝手に呼べなくする。


439:423
09/04/05 19:03:36
>>438
あーなるほどね。
やっぱあるんだ。
サンクス

440:デフォルトの名無しさん
09/04/05 21:04:47
仮想関数として指定するキーワードvirtualは、どれだけ付けるのが正しい?
例えば
class Base
{
public:
virtual void m_func(){std::cout << "Base m_func!" << std::endl;};
Base(){std::cout << "Base Constructor!" << std::endl;};
virtual ~Base(){std::cout << "Base Destructor!" << std::endl;};
};

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

class Derived_Derived : public Derived
{
public:
void m_func(){std::cout << "Derived_Derived m_func!" << std::endl;};
Derived_Derived(){std::cout << "Derived_Derived Constructor!" << std::endl;};
virtual ~Derived_Derived(){std::cout << "Derived_Derived Destructor!" << std::endl;};
};





441:440
09/04/05 21:06:11
んで呼び出す時は
void foo()
{
Base* p=new Derived;
Base* q=new Derived_Derived;
Derived* r=new Derived_Derived;
p->m_func();
q->m_func();
r->m_func();
delete p;
delete q;
delete r;
}

このように、俺はBaseのm_func()にしかキーワードvirtualを付けていないんだが、これであってる?

スレリンク(win板:127番)


442:440
09/04/05 21:09:30
ごめん
別スレで無礼者がいたから
そいつへレスしようとしてたら
間違ってこっちにリンク張っちまった。>>441

マジごめん。


443:デフォルトの名無しさん
09/04/05 21:17:07
virtualつけたメンバ関数は、派生クラスではvirtualをつけてようがつけてまいが関係なく
仮想関数になる

DerivedもDerived_Derivedもvirtualはつけてもつけなくても一緒


444:デフォルトの名無しさん
09/04/05 21:50:28
>>443
ありがとう。

ちなみにどちらでも同じということだが、その場合
virtualは付ける方が良いとか付けない方が良いとかそういう慣習があったりする?



445:デフォルトの名無しさん
09/04/05 21:54:58
>>440のコードを
Baseでvirtualを付けておき、DerivedとDerived_Derivedではvirtual付けない版と、
Baseでvirtualを付けておき、DerivedとDerived_Derivedでもvirtual付ける版と
両方を作ってビルドしてみた。

g++ -O2 ~~.cpp

としたのだが、挙動は一緒みたいだが、バイナリは違うものになった。
何故?


446:デフォルトの名無しさん
09/04/05 22:09:48
-Sで試して確かめるならまだしも…

447:デフォルトの名無しさん
09/04/05 22:24:44
>>446
-Sだったら同じバイナリになったわ。
なんで??

448:447
09/04/05 22:25:58
>同じバイナリ
→アセンブラコード



449:デフォルトの名無しさん
09/04/06 00:14:09
>>444
C++ Coding Standards では派生クラスでもつけたほうがよいと書いてある。
(38項.安全なオーバーライドを身につけよう)

単に利用者に意図を明確にするためだけどね。

450:デフォルトの名無しさん
09/04/06 00:15:07
速度限界まで最適化するときに
virtualってどう扱うべきなのですかね?

451:デフォルトの名無しさん
09/04/06 00:26:22
@Override みたいなのが欲しいよね

452:デフォルトの名無しさん
09/04/06 00:41:43
そこで属性でしょきっと。

453:デフォルトの名無しさん
09/04/06 00:43:53
#define override virtualってうちの会社の元Delphi使いな先輩がやってた。

454:デフォルトの名無しさん
09/04/06 00:53:48
>423
遅レスだけど、削除を別のfriend classに委譲する時なんかで使う。

こんなの
class A {
private:
^A() {};
class deleter {
void operator()(A* target) { delete target; };
}
friend deleter;
public:
boost::shared_ptr<A> creator() { return boost::shared_ptr<A>(new A, deleter()); };
}

455:デフォルトの名無しさん
09/04/06 17:32:53
class Singleton {
 Singleton() {}
 ~Singleton() {}
public:
 static Singleton& Instance() {
  static Singleton instance;
  return instance;
 }
};
みたいなやり方がどっかに載って無かったかな。

456:423
09/04/06 21:40:38
>>454-455
あるのね。
うーん、やっぱ奥が深い。

457:デフォルトの名無しさん
09/04/07 11:04:11
関係ないけど
singletonをtempleteにするとctorはpublicにせざるをえないのかな?
よくそういう実装をみかけるけど、新しいインスタンスを作れるのがイヤなのですが

458:デフォルトの名無しさん
09/04/07 11:20:52
ctorをprivateにしてsingletonをfriendにすればええがな

459:デフォルトの名無しさん
09/04/07 11:22:59
そもそもシングルトンをテンプレートにしてまで量産しようという考え自体が間違いだな。

460:デフォルトの名無しさん
09/04/07 19:15:55
CamelCaseにするかcamelCaseにするかcamel_case(underscore_style)にするか、
その基準とか主張とかメリットとかデメリットを知りたいんだが、
みんなどうしてる?
確かBoostは俺の知る限りunderscore_styleだったと思うのだが。


461:デフォルトの名無しさん
09/04/07 19:27:32
>>459
量産するなんて誰か言ったの?

462:デフォルトの名無しさん
09/04/07 20:02:19
>>461
テンプレートにしているから量産しようとしているとespしたんじゃない?

463:デフォルトの名無しさん
09/04/07 20:05:20
マヌケなespだな

464:デフォルトの名無しさん
09/04/07 20:12:33
どうでもいいがespがスタックポインタに見えてしょうがない

465:デフォルトの名無しさん
09/04/07 20:50:25
URLリンク(d.hatena.ne.jp)
ここで、
>「デストラクタがヘッダ中に記述されてしまっている」ことにある。
>更に言うと、「deleteがヘッダ中に行われてしまっている」ことが問題であり、
>よりつっこんで言うなら「deleteがCHoge::implの定義と別の場所で行われている」ことが問題なのだ。
>つまり、pimplにスマートポインタを使おうとするなら、デストラクタを必ず明示しなければならないのである。
>それも、implの定義(この場合はhoge.cpp)と同じ場所に、だ。
ってあるんだけど、その意味が分からない。
何でダメなの?
つーかコンパイルは一応通ったんだけど。

466:デフォルトの名無しさん
09/04/07 20:52:21
間抜けな設計に合わせてespのレベルも落としたんだろ

467:デフォルトの名無しさん
09/04/07 21:05:05
>>465
まず、「不完全型(名前だけ分かってるけど完全な定義がまだ見えていない型)のポインタのdeleteは危険」
であることを知ってほしい。これはコンパイルは通るけどきちんと動かないことがある。
(その型に自分で定義したデストラクタやoperator deleteがある場合、ちゃんと呼ばれない。)

class CHogeのデストラクタを記述しない場合、コンパイラが勝手に ~CHoge() を作る。
その中でスマートポインタである pimpl のデストラクタが呼ばれ、不完全型であるimplのポインタをdeleteしようとする。

468:デフォルトの名無しさん
09/04/07 21:13:26
未定義動作だからまともなコンパイラなら警告くらい出すはずだけどな
たまたまデストラクタもdeleteも定義してなかったからスルーしちゃったのかな

469:デフォルトの名無しさん
09/04/07 21:53:18
>>467-468
ありがとう。

「pimplがスマートポインタであるために特殊なdeleteが必要である。
だがコンパイル時にはpimplが不完全型であるためにその特殊なdeleteを呼び出すコードが作られない。」
ってことか。

となると、今回のケースでは
CHoge::~CHoge(){}
を自分で明示的に記述したとしても、それをhoge.hに書いている限りは解消されないんだよね。
hoge.cppのCHoge::implクラスの定義の後に自分で明示的に記述するならOKってことですかい?


470:デフォルトの名無しさん
09/04/07 22:00:43
>>469
前半は違う。スマートポインタであることは本質的な問題ではない。
pimplが単なるポインタであっても、 hoge.h でCHogeの定義の中に
CHoge::~CHoge() { delete pimpl; }
と書いたら、全く同じ問題が生じる。

後半はあってる。とにかく、明示的にであれ暗黙的にであれdeleteが出てくるところでは、
そのdeleteされるものの完全な定義が分かっていなければまずい場合があるということ。

471:469
09/04/07 22:25:09
>>470

なるほど。
根本的な問題は「デストラクタが云々」じゃなくて、
「不完全型のポインタのdelete」にあった訳か。

んで、その辺を全部気にせず丸投げしてもいけるのがshared_ptrなのか。
ありがとう。

・・・しかし
>>>468
>未定義動作だからまともなコンパイラなら警告くらい出すはずだけどな
VC++2008で試して見たのだが
>auto_ptrを用いた例ではVC++2008では警告しか吐かれない。
なぜか警告すら出てこなかったなぁ。


472:471
09/04/07 22:29:09
>>468
警告でた。
お騒がせしました。

warning C4150: 'CHoge::impl' 型を削除するため delete 演算子が呼び出されましたが、定義がありません。
: 'CHoge::impl' の宣言を確認してください。


473:471
09/04/07 22:33:37
追記:

g++でも警告出た。
note: neither the destructor nor the class-specific operator delete will be called,
even if they are declared when the class is defined.

bcc5.5.1では警告でなかった。


474:デフォルトの名無しさん
09/04/07 23:21:08
explicitをデフォルトコンストラクタに付ける意味はありますか?
また、explicitを引数を2つ以上取るコンストラクタに付ける意味はありますか?

475:デフォルトの名無しさん
09/04/08 00:39:21
1.デフォルト引数が付いてて、結果的に引数1個で呼べるなら意味がある
2.付けても害はないのでとりあえずコンストラクタには全部付けるポリシーにして付け忘れを防ぐ

476:デフォルトの名無しさん
09/04/08 01:14:57
explicitを付けさせる仕様でなく、
implicitを付けさせる仕様にすべき

477:デフォルトの名無しさん
09/04/08 03:43:39
>>476
いまさら仕様変更されても困るから、そうなってたらいいな、って話にしかならん。

478:474
09/04/08 07:09:56
>>475
なるほど。ありがとう。

479:デフォルトの名無しさん
09/04/08 19:07:19
copy-and-swapイディオムってすげーのな。
これって自作クラスのoperator=のオーバーロードの定義以外に使い道ある?

480:デフォルトの名無しさん
09/04/08 19:11:38
何がすごいの?

481:デフォルトの名無しさん
09/04/08 19:24:53
>>480
例外安全なところ。


482:デフォルトの名無しさん
09/04/08 19:39:37
>>479
コピーしないでスワップするだけなら、
参照型の引数で値を戻す場合にも。
void foo(hoge_t& result)
{
hoge_t x;
//xにあれこれ手を加える
swap(x, result);
}
まあ、何も考えなくていいときには、resultを直接いじることもあるけど。

483:デフォルトの名無しさん
09/04/08 20:12:23
全部正常に終わるまで変更を反映させたくない処理全般に使えるよね。

484:479
09/04/08 20:21:49
>>482-483
ほほー
ありがとう。

485:デフォルトの名無しさん
09/04/08 21:10:57
オーバーロードしたoperator=を
コピーコンストラクタの定義で使っても大丈夫?


486:デフォルトの名無しさん
09/04/08 21:34:30
よゆー
operatorほにゃららは普通の関数と全く同じように呼び出して可。

487:デフォルトの名無しさん
09/04/08 21:38:45
>>482
ドラゴン・スゴイコビッチ!(とてもすごいの意)

用件としては、自作クラスに swap 関数を装備することと、
その swap が例外を投げないようにすること?


488:485
09/04/08 21:49:40
>>486
ありがとう。
コピーコンストラクタ(に限らずコンストラクタ一般)から
メンバ関数を呼び出す時、
construct中なのにメンバ関数を呼び出しても
大丈夫なのだろうかと思ったのだ。。。


489:デフォルトの名無しさん
09/04/08 21:51:32
>>488
virtualなら気をつけないといかんかもしれんが
そうじゃないなら大概大丈夫

490:デフォルトの名無しさん
09/04/08 21:54:37
大丈夫

491:デフォルトの名無しさん
09/04/08 21:56:15
>>489
>virtualなら気をつけないといかんかもしれんが
ああ、
基底クラスのconstruct中にvirtualなメンバ関数呼ぶと
その基底クラスでの対応するメンバ関数が呼ばれるってやつね。
ありがとう。

>>490
ありがとう。

492:デフォルトの名無しさん
09/04/08 22:03:58
C++0xは本当に後 数ヶ月で策定されるんだろうか。
されたとして、ちゃんと動作するコンパイラが出て来るのはいつだろうか。

・・・うむ、心配だ。

493:デフォルトの名無しさん
09/04/08 22:35:04
別に心配することじゃない。
まともなコンパイラが出てから考えればいいこと。
早く出てくれないと困る事情でもあるのか?

494:デフォルトの名無しさん
09/04/08 22:50:26
すまぽとかは早く表順になってほしいなぁ。
もうすまぽを書くために何リットルのインクを消費したことやら。
(インク?)

495:492
09/04/08 22:52:55
>>493
>早く出てくれないと困る事情
いや、全然ないw
g++が速いかVCが速いか。

496:デフォルトの名無しさん
09/04/08 23:00:35
>>493
IntelC++は既にlambda関数がサポートされてるんだけど、IntelC++はコンパイル遅いんでdebugはVCでreleaseはIntelでやってるとlambda関数は使えなくて残念。
boost::lambda使えば済む話ではあるんだけど。


497:492
09/04/08 23:12:20
現在のTR1のライブラリ達は、正直なところ十分動作することが
確認されるまでは使わない方がいいんではないかと思うんだが。
それまではboostのが安心かなぁ。

でも標準に入ってる方が使うのは(気分的に)もっと楽になる事は確か。


498:デフォルトの名無しさん
09/04/08 23:56:20
class A{
public: virtual ~A() = 0;
};

class B :public A {};

class C :public B
{
public: ~C(){};
};

gccでundefined reference to B::~B()って怒られるんだけど、Bでd-tor書かないとダメ?

499:デフォルトの名無しさん
09/04/09 00:13:43
ごめん。純粋仮想d-torに定義書くの忘れてた

500:デフォルトの名無しさん
09/04/09 00:17:10
俺としては以下のやり方でMyClassクラスによるstd::swap関数テンプレートの特殊化を行い、
using std::swap;
swap(x,y);
で特殊化したstd::swap<MyClass>が呼び出せるかと思ったのだが、
以下のやり方だとなにか定義がかぶっているようなことを言われてエラーになってしまう。
再現するソースは次のようなもの。
//以下はMyClass.h
class MyClass
{
char *p;
public:
void swap(MyClass &hoge);
MyClass();
~MyClass();
};
//以下はMyClass.cpp
#include <algorithm>
#include "MyClass.h"
MyClass::MyClass():p("pointer"){}
MyClass::~MyClass(){}
void MyClass::swap(MyClass &hoge)
{std::swap(this->p, hoge.p);}
namespace std
{
template<>
void swap(MyClass &lhs,MyClass &rhs)
{lhs.swap(rhs);}
}

501:500
09/04/09 00:18:28
//以下はmain.cpp
#include <algorithm>
#include "MyClass.h"
int main()
{
MyClass x,y;

using std::swap;
swap(x,y);

return 0;
}
としたら、g++にて
MyClass.cpp:(.text+0x42): multiple definition of `void std::swap<MyClass>(MyClass&, MyClass&)'
main.cpp:(.text$_ZSt4swapI7MyClassEvRT_S2_[void std::swap<MyClass>(MyClass&, MyClass&)]+0x0): first defined here
collect2: ld returned 1 exit status
というエラーが出る。
どうしたらいい??


502:デフォルトの名無しさん
09/04/09 00:31:28
理由は覚えてないけどstd名前空間の中でswapの特殊化しちゃだめだった気がする。
ちょっと俺も確認してくるか。

503:502
09/04/09 00:33:03
別に駄目じゃないか。ごめんスルーしてくれ。

504:デフォルトの名無しさん
09/04/09 00:37:36
>>485
大丈夫だけど、普通operator =ってcopy (construct) and swapで書かない?

URLリンク(ja.wikibooks.org)(Copy-and-swap)

505:デフォルトの名無しさん
09/04/09 00:58:49
>>500
std::swapの特殊化はヘッダに書かないと駄目だろう。
main.cppでは特殊化したstd::swapが見えないから標準のstd::swapが実体化され
MyClass.cppで特殊化した物と衝突してるんだろう。

506:デフォルトの名無しさん
09/04/09 06:57:11
>>504
そうか。
コピーコンストラクタの定義に代入演算子を使うと定義が循環しちゃうのか。

507:500
09/04/09 06:58:19
>>505
なるほど。
std::swapの特殊化をヘッダに書く場合はinline指定しないと、
そのヘッダをインクルードするたびにまたmultiple definitionってなっちゃうかな?

508:デフォルトの名無しさん
09/04/09 08:13:54
>>507
いや、そういう話じゃない。

509:500
09/04/09 08:22:57
>>508
(1)main.cppでは特殊化した定義がその前になされていないから通常通り実体化。
(2)MyClass.cppでも特殊化した。

この(1)と(2)でmultiple definitionってことか。
つーことで
MyClass.hにstd::swapの特殊化を書く(1)
main.cppでMyClass.hをインクルード
ってこと?

510:508
09/04/09 08:24:06
>>507
あ、ヘッダに書かないといけないのは理解してるのか。ごめん

テンプレートの定義は inline じゃなくてもいいよ。 >500 の場合は inline が
適切だと思うけど。

511:デフォルトの名無しさん
09/04/09 08:25:44
これが inline じゃないといけないんなら全部の関数テンプレートが
inline にならないといけなくなるな。

512:インドリ
09/04/09 10:05:14
URLリンク(blogs.wankuma.com)
URLリンク(d.hatena.ne.jp)

513:デフォルトの名無しさん
09/04/09 10:18:24
>>512
広告ウゼェ
URLリンク(info.2ch.net)
> ・投稿者は、話題と無関係な広告の投稿に関して、相応の費用を支払うことを承諾します

514:デフォルトの名無しさん
09/04/09 10:19:49
しかもマルチかよ。何のつもりだ?

515:デフォルトの名無しさん
09/04/09 10:20:30
インドリしゃんに粘着する物好きもいるんですね

516:デフォルトの名無しさん
09/04/09 12:23:10
>>515
粘着の意味わかってんの?

517:デフォルトの名無しさん
09/04/09 14:28:38
C++でGUIのプログラムを作ろうと思うんだが、お勧め開発環境はなにかないか?

518:デフォルトの名無しさん
09/04/09 14:48:04
また環境も書かんと適当に訊くなあ。

519:デフォルトの名無しさん
09/04/09 14:51:01
>>518
OS;XP


520:デフォルトの名無しさん
09/04/09 15:00:29
C++Builder(8万円くらいする)
Turbo C++(C++ Builderの無料版 機能が削られていて少し古い)
Qt Creater(マルチプラットフォームのソフトが作れる コンパイルが遅い)

521:デフォルトの名無しさん
09/04/09 15:08:24
>>520
turbo c++でGUIって開発できるの??

522:デフォルトの名無しさん
09/04/09 15:52:24
できるよ

523:500
09/04/09 22:50:09
>>510-511
そういえば関数テンプレートの定義は
ヘッダに書くけど、それは普通の関数の類推で
inlineじゃなきゃいけないなんて考えちゃだめなんだったな。
Effective C++に書いてあったような気がしてきた。。。
ありがとうお二方。

524:デフォルトの名無しさん
09/04/09 22:53:28
「exit(0)で終了するとデストラクタが呼び出されたり呼び出されなかったりする」
っていうC++の仕様について学べるサイトを教えてください。

巻頭言 2000~
URLリンク(park1.wakwak.com)
一応ググったらこんなのがヒットしましたが、これ以外にも何かオススメをご存じであればお願いします。

525:デフォルトの名無しさん
09/04/09 23:10:23
std::powとかhypotとかをスレッドセーフに実行したいんだけど、おみゃーらどうしてる?
軽いに越したことはないずら

526:デフォルトの名無しさん
09/04/09 23:12:13
常識的に考えればスレッドセーフでないわけがない。
って書こうとしたが、errnoとか気にしている?

527:デフォルトの名無しさん
09/04/10 00:16:23
あれ?そうだったの?errnoは気にしてない。
うーん、じゃあ他のところで変な風になってたのかにゃ・・・?
ありがとうござんした

528:デフォルトの名無しさん
09/04/10 02:35:26
>>524 >>333-

529:デフォルトの名無しさん
09/04/10 08:30:05
errnoを気にするとどうなの?

530:デフォルトの名無しさん
09/04/10 11:55:32
>>529
errnoはグローバル変数なので、
errno = 0;
std::pow(x, y);
if (errno != 0) { /* 失敗 */ }
みたいなコードを書いたときに、powとifの間で他のスレッドによってerrnoが変更されてしまう可能性がある
だから、errnoを気にするとpowとかはスレッドセーフじゃなくなる

たいていのコンパイラにはerrnoをTLSに置いてスレッドセーフにするオプションとかがあるけどね

531:デフォルトの名無しさん
09/04/10 15:48:35
タクティカルレーザーシステム?

532:デフォルトの名無しさん
09/04/10 17:30:34
>>531
いやTrue Love Storyです。

 じゃなくてThread Local Storageです。

533:デフォルトの名無しさん
09/04/10 18:05:46
元気でね 頑張ってね
手紙書くね たまに会えるよね
なんでかな 寂しいのに
寂しいよと 言えなかった

534:デフォルトの名無しさん
09/04/10 19:06:46
wwwwwwwwwwww

535:デフォルトの名無しさん
09/04/10 21:10:40
イイハナシダナー

536:デフォルトの名無しさん
09/04/10 22:17:52
>>530
よく分からんがerrornoへの代入って規格的に許されてたっけ?

537:デフォルトの名無しさん
09/04/10 22:27:30
18歳以上ならeroero挿入おkだよ

538:デフォルトの名無しさん
09/04/10 22:32:32
はいはいエロスエロス

539:デフォルトの名無しさん
09/04/10 23:13:49
18歳以上なのに、いつになってもeroeroの値がインクリメントされず初期値のままです。

540:デフォルトの名無しさん
09/04/11 00:09:13
>>539
君の中ではその変数は1つだけ存在すれば十分だよね。
俺達他人に迷惑書けて欲しくないから、君の実装から外には出さないで欲しいなぁ。

ってことでeroeroは自動的に0に初期化されてます。

541:デフォルトの名無しさん
09/04/11 00:15:47
E2BIGになって困る

542:デフォルトの名無しさん
09/04/11 00:39:57
>>540
static変数ってことか。

543:デフォルトの名無しさん
09/04/11 01:22:23
>>536
大丈夫です
C99(ISO/IEC 9899:1999)の7.5の脚注170に「むしろそうするべき」って書いてある(C++の規格には「Cの規格を見てね」って書いてある)

544:デフォルトの名無しさん
09/04/11 21:07:03
若干スレ違いな気がして申し訳ないんだが、
C++の書籍(他の言語は知らんけど)って正誤表無いor乏しいの多くない?

『Exceptional C++』を買ったんだけど、1ページ目から
誤植と思われる物があって困る。。。

だれか正誤表作ってくれている人とかコミュニティとか無い??

545:デフォルトの名無しさん
09/04/11 21:34:26
グローバルスコープに
std::string foo();
って書いたら、
std::string型を返す、引数のない、fooという名前の関数の宣言になるの?
それとも
std::string型のfooという変数の宣言とデフォルトコンストラクタ呼び出しになるの?

546:デフォルトの名無しさん
09/04/11 21:35:50
>>545
前者
C++は関数の宣言が優先

547:デフォルトの名無しさん
09/04/11 21:37:26
>>546
なるほど。
ありがとう。

548:デフォルトの名無しさん
09/04/11 23:09:01
一応書いとくけど、ローカルスコープでもクラススコープでも同じだから。
ローカルでも関数の宣言は出来るからね。

549:デフォルトの名無しさん
09/04/11 23:16:46
これもちなみに
強制的に変数の宣言とデフォルトコンストラクタと見なさせるには

std::string (foo());

と書けばよかったような
間違ってたらすまん

550:デフォルトの名無しさん
09/04/11 23:27:27
やってみたけどあかんかった
カッコつけても関数宣言と見なされる

std::string foo("");

と何でもいいからパラメータ付けるしかないな

551:デフォルトの名無しさん
09/04/11 23:47:13
>>544
ぐぐれよかす
URLリンク(www.gotw.ca)
URLリンク(www.informit.com)

552:デフォルトの名無しさん
09/04/11 23:49:15
んばば んばんば えらったえらった

553:544
09/04/11 23:51:04
>>551
いや、日本語でググったりピアソンエデュケーション社の
Webページで検索してみたりしたんだが英語は見落としていた。

ありがとう、恩に着る。


554:545
09/04/11 23:55:38
>>548
ローカルでは関数の宣言だけは出来るけど定義はできないんだよね。
ありがとう。

555:デフォルトの名無しさん
09/04/11 23:57:37
>>550
いや、カッコつけなければいいだけ。

556:デフォルトの名無しさん
09/04/12 00:31:48
>>555
じゃなくてstd::stringのコンストラクタ呼び出したいんだけど

557:555とは別人
09/04/12 00:35:04
>>556
だから括弧つけなければいいなじゃないの?
std::string foo;
これでデフォルトコンストラクタ呼び出しになるでしょ?

558:デフォルトの名無しさん
09/04/12 00:36:12
デフォルトコンストラクタの話じゃなかったのか。
デフォルトじゃないなら引き数書くのは当たり前だろ。

559:デフォルトの名無しさん
09/04/12 00:46:26
なんだ?
未来指向なプログラムの話か?

560:まとめ
09/04/12 00:53:22
要は
1.
std::string str="hogehoge";
ならstrの宣言&"hogehoge"を引数にとるコンストラクタの呼び出しとなる。
2.
std::string str("hogehoge");
って書いてもstrの宣言&"hogehoge"を引数にとるコンストラクタの呼び出しとなる。
3.
std::string str(const char* arg);
ならstd::string型を返し、const char*を引数にとる関数strの宣言となる。

これを引数なしverにすると

1'.
std::string str;
ならstrの宣言&デフォルトコンストラクタの呼び出しとなる。
2'&3'.
std::string str();
ならstd::string型を返し、引数のない関数strの宣言となる。

ってことだよね。
たぶんこのスレのみんなは分かっているけどレスが言葉足らずでカオスになっているだけかと。

561:デフォルトの名無しさん
09/04/12 01:17:31
>>556
もし、本当に「デフォルトコンストラクタを呼び出したいだけ(変数は用意したくない)」なら
std::string();
と書けば呼べるだろうね。
もちろん、ソース上には現れない一時変数が用意されるだけだけど。

普通に「デフォルトコンストラクタで初期化される変数を用意したい」ならば
皆が書いているように
std::string str;
とすれば良いだけ。

562:デフォルトの名無しさん
09/04/12 15:26:49
純粋なC++で、初心者でもないのにgotoを使う人って見たことある?
やるとしたらスパゲッティにならないで使える人なんだろうけど。



563:デフォルトの名無しさん
09/04/12 15:59:10
goto使えば二重三重ループから一気に抜けられるじぇ

564:デフォルトの名無しさん
09/04/12 16:16:02
あなた天才

565:562
09/04/12 16:26:45
まあネストしたループから一気に抜けるって使い方か。

別の方法としてわざと例外をthrowしてるヤツがいたけど
それよりはマシか。

変なフラグ変数用意するくらいならgotoのがいいのだろうか?


566:デフォルトの名無しさん
09/04/12 16:28:22
フラグ変数なんか使うな
プログラムの見通しが悪くなる

567:562
09/04/12 16:31:09
>>566
ですよねー。
俺もそう思うよ。

サンプルソースならともかく
flagとかhogeっていうフラグ変数を
用意しているヤツを見ると
もう頭痛がしてくる。



568:デフォルトの名無しさん
09/04/12 16:35:57
クラス設計で、メンバ関数はどの順番で記述する?

例えば基底クラスでpolymorphicな使い方を想定しているとして。
以下public指定なものだけを書く。

class ~~{
1.コンストラクタをずらずらと。
2.virtual デストラクタ。
3.swap()メンバ関数
4.これら以外の普通のdo_something()メンバ関数をずらずらと。
5.operator=
6.operator+
7.以下必要ならoperator云々
};

ってな感じにすれば良い?
今ひとつ経験不足でどんな感じが良いのかわからんのだ。


569:568
09/04/12 16:36:50
>基底クラスでpolymorphicな使い方
ってまあ要するに基底クラスのポインタに派生クラスのポインタを変換して使うつもりって言いたい。


570:デフォルトの名無しさん
09/04/12 16:37:32
まぁ、多重ループから一撃で抜けるなら
その部分をカプソー化してれつるんで抜ける方が
スマートな気もするよね。

571:デフォルトの名無しさん
09/04/12 16:38:34
>>570
れつるん
って南蛇井?

572:571
09/04/12 16:39:47
>>570
ああreturnか。

573:デフォルトの名無しさん
09/04/12 16:41:17
>>566
下手するとgotoなんかよりずっとスパゲッティーになるな
フラグ変数が2つ出てきたり、状態が3つとかあったりすると死ねる

574:デフォルトの名無しさん
09/04/12 16:44:14
>>573
やっぱ2重程度ならともかくそれ以上多重にネストしているあたりから
おかしくなり始めていると考えた方が良いのかなぁ。


575:デフォルトの名無しさん
09/04/12 20:26:39
フラグって一切使っちゃダメなん?
一切使うな的なことを初めのころ本で呼んで、
それ以来、可能な限り使わない方法を考えてる。
フラグを使わない方法を考えるだけで1日潰すなんてザラ。

でも、実際仕事を始めたら、普通にみんな使ってるし、
大体、DB自体がフラグのカラムでいっぱいだし、
そうなるとコード側でもフラグを操作しないとダメになる。

何が言いたいかっつーと、
フラグを使いまくってる職場のプログラム設計がおかしいのか、
フラグ排除主義の過激派が悪いのか、真理を教えてくれ

576:デフォルトの名無しさん
09/04/12 20:36:26
別に、そう深刻に考える問題でもないと思うけど。
>>567は逆に考えれば、明快な名前を持つフラグ変数ならマシってことでもある。

577:デフォルトの名無しさん
09/04/12 21:07:24
フラグや多重ループはベタなコードを一度書いてみてジックリ考察すれば
単純なクラス構造に落とせると思うっス 使い捨てクラスが増殖するけど
後の状態変数の把握のし易さは別次元。

578:デフォルトの名無しさん
09/04/12 21:53:11
まぁ、アジャイル・プラクティスの教えに従えば、何事もバランスが大事。
そして、ダメだとわかったときにはリファクタリングする勇気。

でも、できればフラグやgotoは減らしていきたい。

579:デフォルトの名無しさん
09/04/12 21:58:37
gotoなんか使ってる奴はダメだね
男ならsetjmp/longjmpだろ

と行きたいところだがある意味>>565で既出だった

580:デフォルトの名無しさん
09/04/12 22:02:40
恩師、goto熊男先生いわく、

「ノォ!」

なので、gotoは使っちゃいけないと思うな。
(おっさん限定ネタ)

581:デフォルトの名無しさん
09/04/12 22:07:05
BreakTwoLevelsException

582:デフォルトの名無しさん
09/04/12 22:10:20
いや、最初の論点は
「goto使用を避けるためにフラグを使う」というのが最悪、ってことだろ。
もちろんフラグなんて可能な限り使わないほうが良いが、避けられないケースはある。

また、よく言われるループ内のswitchからの脱出の話題で
「switch使うな、classにしろ」という論も
猫も杓子もそうしろと言い出すのはナンセンスとしか言い様が無い。
「return使え」も同様。

要は、臨機応変に適材適所で手元にある道具を使え、ってことだ。

583:デフォルトの名無しさん
09/04/12 22:20:54
内部ループ部分の関数括りだしや、contiue を活用すれば、二重以上のループは
殆ど登場しないから、個人的には goto は要らないな。
STL やファンクタも併用すれば、ループそのものの登場機会が減るし。

584:デフォルトの名無しさん
09/04/12 22:22:10
このスレって荒れないね。
すばらしい。
理性的な人がそろっているな。



585:デフォルトの名無しさん
09/04/12 22:33:13
C++は、使う人が理性的でないと、大変なことになるからかもね

586:デフォルトの名無しさん
09/04/12 22:35:43
でも、スコットメイヤーもハーブサッターも
著書の中で毒舌はきまくりだよ。

587:デフォルトの名無しさん
09/04/12 22:45:51
>>581
BreakがTwoLevelsかどうかはcatch節によるんで、その名前はあんまりです。

588:デフォルトの名無しさん
09/04/12 23:09:04
C++で正常系なのに例外を使うなんて信じられないっす

589:デフォルトの名無しさん
09/04/12 23:12:42
局地的な使い捨てフラグの禁止は古い最適化思想の名残のような感じがするけどなぁ。

大局的にはフラグ専用の変数を用意してあちこちで状態を変更しまくってると
・フラグの状態を変更すべき処理を追加・変更したのにフラグの変更処理を忘れる
・フラグの今の状態がどこで変更された結果なのかがわからなくて状態の信頼性に欠ける
とかの問題がでやすくなるから気をつけろってことだろ。

590:デフォルトの名無しさん
09/04/12 23:21:33
みんなそういう意味で言ってたと思うよ。

591:デフォルトの名無しさん
09/04/12 23:31:53
ユーザ定義リテラル使って、

throw "hoge_loop"_break;

とか。

592:デフォルトの名無しさん
09/04/12 23:51:00
ある自作関数が1行で終わるとても短いstatic関数だったので、
それを実装ごと丸々ヘッダhoge.hに書きました。
特にinline指定はしなかったのですが、
そのhoge.hをインクルードするソースファイル.cppが複数あるにもかかわらず
g++で問題無くコンパイル・リンク・実行できました。

普通の関数だったらmultiple definitionとか言われるはずだと思うのですが、
static関数なら大丈夫だったりするのでしょうか?


593:デフォルトの名無しさん
09/04/13 00:04:18
はい。ただし無駄です。

594:デフォルトの名無しさん
09/04/13 01:33:22
>>584
そう言われると、なんだか最近まったり進行している気がしてくる。

595:デフォルトの名無しさん
09/04/13 02:47:58
>>592
(メンバ関数でない)static関数とはまさにそういうものだろ。

596:デフォルトの名無しさん
09/04/13 05:50:11
>>586
毒舌っていうのは理性と知性によって導き出されるものだよ。
馬鹿な人間が感情のままに吐くのは、面白味も攻撃力も無い単なる罵倒。

597:デフォルトの名無しさん
09/04/13 15:16:18
>>596
まぁ、すてきな毒舌なこと。

598:デフォルトの名無しさん
09/04/13 15:51:35
>>596
>馬鹿な人間が
自虐?

599:デフォルトの名無しさん
09/04/13 16:04:21
ごめん、何に噛み付いてるのかよくわからない。
メイヤーズやサッターが理性的でないと言いたいのか、
それとも「毒舌というのが知性や理性の欠如から出るものなんだ」と主張したいのか、
それとも普段の自分が否定されたみたいで悔しいのか。

600:デフォルトの名無しさん
09/04/13 16:19:14
ごめん、何を必死に弁解してるかわからない。


いや、マジで

601:デフォルトの名無しさん
09/04/13 16:23:39
>>599
かみつくという認識もないくらい、ただの脊髄反射煽りだから気にすんな。

602:デフォルトの名無しさん
09/04/13 16:24:42
>>601
そうやって煽り返すから荒れるんだよ
もう少し自重しようよ

603:デフォルトの名無しさん
09/04/13 17:02:39
>599はどのレスの人間で、どのレスに噛み付かれたのかと思ったんだ?


604:デフォルトの名無しさん
09/04/13 17:21:35
メイヤーズやサッターが知性も理性の欠片もない。
面白味も攻撃力も無い単なる罵倒。

605:デフォルトの名無しさん
09/04/13 17:40:10
わどらー

606:デフォルトの名無しさん
09/04/13 18:21:38
プログラム中でint型の変数を2種類(a,bとする)定義し、その2つによって複
素数の型の要素を持つa列b行の2次元配列を定義したいのですが、

------
#include <iostream>
#include <complex>

using namespace std;

void main(){
 int a,b;
 complex<double> c[][];

 cin >> a;
 cin >> b;

 complex<double> *c = new int[a][b];
------

これでエラーが多発してしまいます。
配列の定義に問題があれば教えていただけないでしょうか。

607:デフォルトの名無しさん
09/04/13 18:25:00
std::vector<std::vector<std::complex<double> > > c(a, std::vector<std::complex<double> >(d));

608:デフォルトの名無しさん
09/04/13 18:27:27
>complex<double> *c = new int[a][b];

型が違うからね。
>>607 の方法が一番素直なやり方と思う。

609:デフォルトの名無しさん
09/04/13 18:28:31
×(d)
○(b)

610:デフォルトの名無しさん
09/04/13 18:29:35
std::vectorならresize()メソッドが使えるから後から大きさを変更する事もできる
アクセスは c[1][2] のように書ける

611:デフォルトの名無しさん
09/04/13 18:51:41
Boostを使ってもいいなら、boost::multi_arrayを検討してみるのもいい。

612:デフォルトの名無しさん
09/04/13 22:26:09
file 1

template<class T> class Parent {
void Umu() { Child* p = new Child; p->Method() }
};

file 2

template< class T > class Child {
void Umaseru() { m_pParent->Umu(); }
}

テンプレの場合、実装部分をcppに退避する事ができないので、
上記のような相互参照するクラスのテンプレートって実装できないのでしょうか?

613:デフォルトの名無しさん
09/04/13 22:29:15
先行宣言すればいいよ

614:デフォルトの名無しさん
09/04/13 22:46:20
先行宣言しても、そのクラスのメンバ呼出ししてたらコンパイルできない気がする。

615:デフォルトの名無しさん
09/04/13 23:03:59
基底クラス内にあるクラスは派生クラスで特殊化可能ですか?

616:デフォルトの名無しさん
09/04/14 07:26:03
a Gr bner basis

617:デフォルトの名無しさん
09/04/14 09:59:34
template<class T> class Parent {
void Umu();
};

template< class T > class Child {
void Umaseru() { m_pParent->Umu(); }
}

template<class T>
void Parent::Umu() { Child<T>* p = new Child<T>; p->Method() }

618:デフォルトの名無しさん
09/04/16 06:30:03
質問です。お時間あればよろしくお願いします。
--------------------------------
class Base
{
// 省略
    virtual size_t getSize() const { return sizeof(*this); }
};

class Derived : public Base
{
// 省略
};

int main()
{
    Derived d;
    d.getSize();

--------------------------------
d.getSize()の値がBaseなのですが、自分が期待していたのはDerivedのサイズの取得です。
DerivedではgetSize()を定義せず、
Derivedのサイズを返すメンバ関数をBaseで定義することはできるでしょうか?
何か良い方法があれば教えていただきたいです。


619:デフォルトの名無しさん
09/04/16 06:57:06
>>618
もし、Derivedにprivateなメンバ関数を追加することが許されるのであれば、
BaseとDerivedに、それぞれsizeof(Base)とsizeof(Derived)を返すprivateでvirtualなメンバ関数を追加する。
で、Base::getSize() からはそれを呼び出すようにする。

原則としてsizeofの値はコンパイル時に決まるのであり、実行時の型で決まるものではないことに注意。
(C99の可変長配列は例外となる。)

620:デフォルトの名無しさん
09/04/16 08:53:01
>>619
早速の返答ありがとうございます。
なるほどサイズは動的に決まるわけではないんですね。
そもそもこんな事をしたくなる設計がよくないんでしょうかね…


621:デフォルトの名無しさん
09/04/16 10:19:50
ifstreamでバイナリファイルを読み込んでいます。
現在の読み込み位置のアドレスを知る方法はないのでしょうか?
operator>>で読み込むたびにカウントするしかないのでしょうか?

622:デフォルトの名無しさん
09/04/16 11:18:42
>>621
tellg()

623:デフォルトの名無しさん
09/04/16 12:05:18
ファイルサイズはseek+tellで得るのが定石だった頃が俺にもありました

624:デフォルトの名無しさん
09/04/16 13:02:25
>>620
もしよければ、なんでサイズを取得する必要があるのかを教えてくれないか。
今までそういう場面に遭遇したことがない。
インスタンスの正体を調べたいなら、getClassのインプリメントなりdynamic_caseで済むと思うが・・・

625:592
09/04/16 13:48:03
>>593
>>595
ありがとうございます。

どうやら私のstatic関数への理解がおかしいみたいなので、
勉強してきます。

なんか同じstaticという予約語を使っていながら、
使い方しだいでだいぶ意味が違う気がするんですが・・・。


626:デフォルトの名無しさん
09/04/16 17:28:05
>>625
> なんか同じstaticという予約語を使っていながら、
> 使い方しだいでだいぶ意味が違う気がするんですが・・・。
いかにもそのとおり。
それが嫌なので、C++ではグローバルでstaticなものを宣言する代わりに、無名名前空間が推奨されている。

627:621
09/04/16 19:05:12
>>622
ありがとうございます
おかげさまで tellg, tellp, seekp, seekg 等を知ることができ
無事プログラムを動かすことができました

628:デフォルトの名無しさん
09/04/16 21:08:54
C++のifstreamではtellp==tellg、seekp==seekgなんだよな

stringstreramではtellp!=tellg、seekp!=seekgなのに

この事に気づくのに手間取ってしまった

629:デフォルトの名無しさん
09/04/16 22:30:06
ifstreamにtellp、seekpは無いっしょ

630:デフォルトの名無しさん
09/04/16 22:40:31
>>629
ある
普通に使える
が、tellpはtellgと同じ意味になるし、seekpはseekgと同じ意味になる
やってみそ

631:デフォルトの名無しさん
09/04/16 22:44:14
たしかfstreamでもpとgのシーク位置は連動するはず。

632:629
09/04/16 22:53:10
>>630
fstreamにはpとg両方あるけど、ifstreamにはgしかなくね?

633:デフォルトの名無しさん
09/04/16 22:58:26
>>632
悪い
fstreamでなくてifstreamだったか
酔ってるスマソ

634:デフォルトの名無しさん
09/04/17 00:17:13
Windows XPのコマンドプロンプト画面から
 g++ hoge.cpp piyo.cpp
みたいな感じで使えて、
標準準拠性も良くて、無料な
コンパイラ(リンカ付き)ってありませんか?

g++を使っていて、エラーメッセージがイミフな時に別のコンパイラで試すのに使いたいんです。
VC++だとコマンドから使えないですよね?


635:デフォルトの名無しさん
09/04/17 00:18:42
つかえますよ。

636:デフォルトの名無しさん
09/04/17 00:22:43
>>635
まぢすか。
VC++が使えれば文句ありません。

もう一度調べ直してきます。

637:デフォルトの名無しさん
09/04/17 05:27:19
windowsで無料で使えて新しめってg++とcl位?


638:デフォルトの名無しさん
09/04/17 06:39:15
ちょっとスレ違いになってしまうかもしれないんですが、
巷で言われているメモリプール化というのをしようとしてるんですけど
概念として教えてもらいたいものがあります。

ヒープ領域とは全体の確保されたメモリ
チャンク領域とはこれから使う為にヒープ領域から必要なだけ小出しに取ってきたメモリ

って感じでいいんでしょうか?
プールとは?チャンクと同じような概念でよろしいでしょうか?


639:デフォルトの名無しさん
09/04/17 07:06:21
ヒープ領域 newでシステムから借りてきたメモリ領域。

プール=確保したもの、プール金とかのプールと意味は同じ。予めシステムから借りておく。
お金が必要なたびにいちいちATMに逝くのではなく、必要になる前に家に現金を置いておくイメージ。

チャンク=こまぎれ。
数バイト毎とかでチマチマ確保すると効率が悪いので、大きな単位で確保する。

必要な額だけをATMからおろすのではなく、必要な額を10万円単位で切り上げておろす、みたいなイメージ。
1万円必要になったら10万円おろし、
11万必要になったら20万円おろす。

640:デフォルトの名無しさん
09/04/17 08:00:39
その手の比喩は、7-8割理解できている人間に「トドメの刺す」のには有効だけど、
初期に読まされると余計混乱すると思うよ。

641:デフォルトの名無しさん
09/04/17 08:03:11
×トドメの ○トドメを

>>638
「Effective C++」に確か、実例つきで説明があったはずだから、
それを読んでみるといいんじゃないかな。

642:デフォルトの名無しさん
09/04/17 10:10:02
~_tはtypedefの証というけど、
これは規約上予約されている?
例えば自分で
numeric_t
とかしちゃだめ?

643:デフォルトの名無しさん
09/04/17 10:33:18
全然。いくら使っても大丈夫。_tamuraとか__tamuraとかも衝突しない限り使って大丈夫。

644:デフォルトの名無しさん
09/04/17 10:52:01
>>643
ありがとう。
MY__M__A__C__R__O
とか予約されてるじゃん。これと同じ感じで予約されてたらやだなと思ったのだ。

645:デフォルトの名無しさん
09/04/17 12:03:25
> MY__M__A__C__R__O
なんだ俺の知らない世界の話か
Cのプリプロに名前を教え込むのは極力避けたい

646:デフォルトの名無しさん
09/04/17 12:50:47
>>643
_tamura はグローバルでは予約されてるから使えない。
__tamura はどこでも予約されてるから使えない。

647:デフォルトの名無しさん
09/04/17 12:53:10
// main.cxx
namespace {
typedef int _INT;
}

int main() {}

std::でもグローバルでもないならおk?

648:デフォルトの名無しさん
09/04/17 12:58:46
>>647
_INT みたいにアンダースコア~英大文字で始まる名前は
ダブルアンダースコアを含む名前と同じくどこでも予約。ダメ。

649:デフォルトの名無しさん
09/04/17 13:04:41
>>645
_が二連続した名前は予約済みなんだよ。


650:デフォルトの名無しさん
09/04/17 13:04:42
s/_INT/_iNT/

# おk?

651:デフォルトの名無しさん
09/04/17 13:07:51

URLリンク(msdn.microsoft.com)(VS.71).aspx
ここの
 予約名の形式
ってところに書いてあるね。

652:デフォルトの名無しさん
09/04/17 13:12:26
どこの独自コンパイラだよ^^
_hoge も __fuga もうちのコンパイラは全然大丈夫だよ。

653:デフォルトの名無しさん
09/04/17 13:14:29
>>647,650
アンダースコア~英小文字で始まる名前はグローバルで予約されてる。
処理系がグローバルに _iNT って名前を置いてたら曖昧になっちゃうから、
すぐに未定義動作とは言えなくてもやっぱりダメだろう。

早い話、そもそもアンダースコア始まりの名前なんか使わなきゃいい。

654:デフォルトの名無しさん
09/04/17 13:17:02
>>652
予約されてるかどうかが問題なんだよ。
今大丈夫でも、コンパイラを変えたりコンパイラのバージョンやコンパイルオプションを
変えたりしただけでエラーになるコードじゃ困るだろう。

655:デフォルトの名無しさん
09/04/17 13:20:52
>>653
すべての識別子において、
ファイルスコープを持つ ならば グローバルスコープを持つ
ということ??

656:655
09/04/17 13:24:20
自己解決しました

657:デフォルトの名無しさん
09/04/17 13:36:11
>>639
なるほど!
>>641
あー、よく聞く本です。ちょっと探してこようかな…


658:デフォルトの名無しさん
09/04/17 22:21:47
演算子について教えてください。

(見やすさとか保守性とかは考えないとしてC++の規格上)
a と b が int 型の時、
以下の表現は問題無いでしょうか?

『 b ? a=b : a++; 』

? : よりも = の方が優先順位は低いのですが、
? と : は2個セットの演算子なので、

(b ? a) = (b : a++);

このように別々になることができず
b ? (a=b) : a++;
の解釈しか出来ないはずで、
VCでも正常にコンパイル出来、ちゃんと動作します。


659:デフォルトの名無しさん
09/04/17 22:30:15
>>658
うん、大丈夫。
文法上、「論理和式 ? 式 : 代入式」となっているので問題ない。
そう、ついでに言えば、?と:の間に?:を入れ子にもできてしまうということも導かれる。

660:デフォルトの名無しさん
09/04/17 23:25:55
>>659
ありがとうございます


661:デフォルトの名無しさん
09/04/17 23:54:12
暗黙の型変換について教えてください。

以下のようなものはdoubleからintへの暗黙の型変換は行われないのでしょうか?
私の環境ではコンパイルエラーになってしまいます。

int a[1.0];
int b = 1%1.0;
int c = 1&1.0;
enum{d=1.0};

暗黙の型変換が行われない例は他にありますでしょうか?


662:デフォルトの名無しさん
09/04/18 00:25:24
doubleの値はintでは表現できないので暗黙に変換できない。
基本的に情報落ちが発生する方へは暗黙で変換できない。

663:デフォルトの名無しさん
09/04/18 00:28:31
処理系によるぞ

VC9だと、

int i = 1 * 0.8;

は warning 扱いになる。(int)で黙る。


664:デフォルトの名無しさん
09/04/18 00:30:25
型変換にはいろいろあるんだぞー
算術式での格上げとか暗黙の型変換とか

665:おもち
09/04/18 00:39:16
プログラム初心者なのですが、いい参考書などないでしょうか?

666:デフォルトの名無しさん
09/04/18 00:41:43
>>665
死ね

667:デフォルトの名無しさん
09/04/18 00:44:18
>>666
久しぶりに激しくワラタwwwwwwwwwwww
・・・俺も寂しいな

>>665
感覚を養うために難しい本じゃなくまず
センスオブプログラミングみたいな素養本を読め
言語本は辞典代わりで十分

668:デフォルトの名無しさん
09/04/18 00:47:52
初心者がC++・・・うーむ。
大概の入門書はCを知っていることを前提に書かれているからなぁ。
ところで、大昔javaが出たての頃に読んだ入門書は
C++を知っていること前提みたいな内容だった。
どこでもかしこでもC++との比較が載っていて、
そんなのが全体の1/4くらいを占めていた。

何も知らないで使えるのはBASICとかRubyとかそのへんかな。

669:デフォルトの名無しさん
09/04/18 00:56:59
コンピュータのことを知らなくてもできるのはhaskellかな…
別の知識がいるけど、基本は因数分解と展開(四則演算より単純な算術)なんで
人によっては普通の言語よりわかりやすいのかもしれない
ついでにC++は普通の言語と関数型言語の難しいところだけを集めたような言語だと思ってる

670:デフォルトの名無しさん
09/04/18 01:11:16
ぶっとんでるな

671:デフォルトの名無しさん
09/04/18 02:00:40
>>662 >>663 >>664
関数の引数やコンストラクタはdoubleからintに暗黙的型変換が行われますよね?

int f(int a){ return 0 };
f(1.0);

int a = 1.0;

とかは大丈夫なはず。

これが大丈夫で、>>661 がダメだというのは、
規格書のどの辺に書かれているのですか?
もしわかれば教えていただけないでしょうか。


672:デフォルトの名無しさん
09/04/18 02:06:18
自分で探せやカス

673:デフォルトの名無しさん
09/04/18 02:15:35
>>661
> int b = 1%1.0;
がdoubleに余剰演算かけようとしてエラーになってるんじゃないの?
式の中での暗黙の型変換なんだから1の方がdoubleに変換されて
> int b = 1.0%1.0;
になると思うんだが。

>>671
それは代入時の暗黙の型変換なんだから左辺側に変換される。

674:デフォルトの名無しさん
09/04/18 08:12:20
>>673
たとえば関数なら、

int a(int x,int y);
int a(double x,double y);
int b(int x,int y);
が定義されてたら、

a(1,1.0) は汎整数昇格の方が優先される為、
a(1.0,1.0) となりますが、
b(1,1.0) は b(1.0,1.0) の定義がないので
b(1,1) と変換されると思います。

%演算子の場合も同じように、1.0%1.0の定義が無いため
同じように1%1と型変換されたりしないのでしょうか?

あと、
int a[1.0];
enum{d=1.0};
これはNGですか?


675:デフォルトの名無しさん
09/04/18 10:33:21
>674
> 5.6/2
>The operands of * and / shall have arithmetic or enumeration type;
>the operands of % shall have integral or enumeration type. The usual
>arithmetic conversions are performed on the operands and determine
>the type of the result.

usual arithmetic conversion は 5/9 で規定されていて幅が広がる方向の
変換しか規定されていない。

>664 や >673 の言っている通り、どういう時にどういう変換がかかるかは一つじゃない。

676:デフォルトの名無しさん
09/04/18 10:46:32
> あと、
> int a[1.0];
> enum{d=1.0};
> これはNGですか?

integral constant expression ではないので NG。
論拠は7.2/1、8.3.4/1、5.19/1。

677:デフォルトの名無しさん
09/04/18 10:50:16
7.2/1、8.3.4/1、5.19/1って何を見ればいいの?
ネット上で閲覧できるもの?

678:デフォルトの名無しさん
09/04/18 11:02:45
ANSI規格。

679:デフォルトの名無しさん
09/04/18 11:05:07
で、それはネット上で閲覧できるもの? URLは?

680:デフォルトの名無しさん
09/04/18 11:21:06
ドラフトならタダで見れるだろ

681:デフォルトの名無しさん
09/04/18 11:29:25
で、URLは?

682:デフォルトの名無しさん
09/04/18 11:41:50
自分でググれよ

683:デフォルトの名無しさん
09/04/18 11:45:03
出た、「ググれよ」ww

684:デフォルトの名無しさん
09/04/18 12:11:49
そりゃ出るだろう。出る箇所だもの。

685:デフォルトの名無しさん
09/04/18 12:24:34
URLリンク(www.open-std.org)

この程度もぐぐれないのならネットやるなよ

686:デフォルトの名無しさん
09/04/18 12:33:52
>>675 >>676
ありがとうございました。
書かれている場所まで記述していただいて
非常に参考になりました。


687:デフォルトの名無しさん
09/04/18 13:04:10
C++のANSI規格が見られるURLを教えてください。

688:デフォルトの名無しさん
09/04/18 13:14:09
>>687
ありません
購入しましょう

689:デフォルトの名無しさん
09/04/18 13:20:08
一次ソースはISOな。
日本語訳がJISのサイトで閲覧できる。

690:デフォルトの名無しさん
09/04/18 13:21:07
で、URLは?

691:デフォルトの名無しさん
09/04/18 13:24:06
自分でググれよ


692:デフォルトの名無しさん
09/04/18 13:26:45
出た、「ググれよ」ww

693:デフォルトの名無しさん
09/04/18 13:31:23
そりゃ出るだろう。出る箇所だもの。

694:デフォルトの名無しさん
09/04/18 13:33:58
URLリンク(www.open-std.org)

この程度もぐぐれないのならネットやるなよ

695:デフォルトの名無しさん
09/04/18 13:34:11
URLリンク(www.open-std.org)

この程度もぐぐれないのならネットやるなよ

696:デフォルトの名無しさん
09/04/18 13:35:31
精神レベルの低い、幼稚なお子ちゃまがよぉ、軽々しく死ねとか言うなよ?
お前を育てた奴は人間社会では、かなりレベルの低いバカだったんだな。
育てられたお前がかわいそうとか思わない。大人になって苦労するのはてめぇ。
いつか死ぬから、バカな存在として一生を無駄に過ごしなさい。

697:デフォルトの名無しさん
09/04/18 13:37:02
誤爆

698:デフォルトの名無しさん
09/04/18 13:39:06
軽々しくググれとか言うなよ

699:デフォルトの名無しさん
09/04/18 13:40:32
こんなものは最初からテンプレに入れとけって話だよ。
お前らの怠慢を質問者になすりつけるな。

700:デフォルトの名無しさん
09/04/18 13:40:38
どうかググってくださいお願いします。


701:デフォルトの名無しさん
09/04/18 13:44:37
人にググれという前に、自分でググって見つけたURLを貼りなさい。

702:デフォルトの名無しさん
09/04/18 13:51:04
で、何のURLを貼って欲しいの?


703:デフォルトの名無しさん
09/04/18 13:58:13
C++のANSI規格が見られるURL

704:デフォルトの名無しさん
09/04/18 14:01:12
とあるライブラリを使おうと思ったら、コールバック関数がCの関数ポインタでした。
データも渡したいんですが、関数オブジェクトが使えないので困っています。
データをグローバル変数にするしか方法はないのでしょうか?

705:デフォルトの名無しさん
09/04/18 14:03:14
とりあえず、使いたいライブラリの機能と、コールバック関数と、渡したいデータを教えてください。

706:デフォルトの名無しさん
09/04/18 14:14:28
>>703
URLリンク(www.jisc.go.jp)
へ行ってX3014で検索してこい。章番号は変わらないはずだから。
ISOもANSIもJISも売り物なので、ちゃんとした物は金を払わなければ見られない。
ダウンロード販売のURLも貼ろうか?


707:デフォルトの名無しさん
09/04/18 14:14:42
そういうコールバックは、データを保持できるvoid *をペアで登録することができて
そいつが引数としてコールバックに渡される仕様になってるはずだが
そうでないならあきらめな

708:デフォルトの名無しさん
09/04/18 14:18:02
>>706
ちゃんとした物とちゃんとしてない物は何が違うの?

709:デフォルトの名無しさん
09/04/18 14:23:52
>>708
ちゃんとしていない物=非合法なコピー品。
提供した者の手が後ろに回る可能性がある。

あと、JISの規格書なんかは閲覧は出来てもダウンロードしてオフラインで見ることは出来ない。


710:デフォルトの名無しさん
09/04/18 14:26:02
>>709
ちゃんとしていない物=非合法なコピー品が何故公式ページからリンクされてるの?

711:デフォルトの名無しさん
09/04/18 14:30:52
まずはどこからどこへリンクされているのかURLを示せよ。
ISOのストアで販売しているものをISOが別のページでタダで配るわけないだろ。


712:デフォルトの名無しさん
09/04/18 14:35:48
>>711
誰に言ってるの?

713:711
09/04/18 14:37:45
>>712
>>710へ言っている。

714:デフォルトの名無しさん
09/04/18 14:38:40
>>707
ありました。
thxでした。

715:デフォルトの名無しさん
09/04/18 14:42:56
>>713
URLリンク(www.jisc.go.jp)
から
javascript:openPDF('X3014,01');
でPDFが開く。

716:デフォルトの名無しさん
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