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

C++相談室 part13

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの引き篭もり NGNG
怪しい仕様は細々ありますが大丈夫です!
elegantなソースを目指してね。

( ^-゚).。o(きっと関連URLは >>2-5 辺りだよ)
0685デフォルトの名無しさんNGNG
ところでこの板、連続書き込みが規制されてない?
今は串を変えて書いてるけど、プロキシ使ってる人は、まとめて規制食らっ
ちゃうよ。
0686683NGNG
>>684
ありがとうございます。よく分かりました。
0687デフォルトの名無しさんNGNG
void penis_fumble(){ (;´Д`)ハァハァ; }
0688デフォルトの名無しさんNGNG
gotcha!
0689デフォルトの名無しさんNGNG
>>683
メンバ関数のグループ化と規格化
「○○対応をうたうクラスにはこんな関数セットを用意すること」
0690デフォルトの名無しさんNGNG
class A
{
};

class B : public A
{

};

というのがあり、

A* boo(A* obj);

という関数なら、クラスAクラスBのどちらのオブジェクトもとれるのは分かるのですが、

A& boo(A& obj);

なら、Aしか引数,戻り値にすることはできませんか?
0691デフォルトの名無しさんNGNG
やってみりゃいいだろ

B b;

A& boo(A& obj)
{
return b;
}

main()
{
boo(b);
}
0692デフォルトの名無しさんNGNG
>>690
Bもできます
自分で試すきないの?
0693690NGNG
すいません。聞きたかったことを間違えました。

A boo(A& obj)
{
B b = new B();
return b;
}

という場合に、bを返したら、どうなりますか?
外で

B b = (B)boo(obj);

みたいなのはできないんでしょうか?
0694デフォルトの名無しさんNGNG
return *b;
0695デフォルトの名無しさんNGNG
どうでもいいが激しくわかりづらいソースだな。AとかBとか。
0696デフォルトの名無しさんNGNG
>693
実体を基底クラスにキャストするとオブジェクトのスライシング、派生クラス分の
オブジェクトが捨てられて基底クラスに詰め込まれる、が起きる。

ポインタ・参照の場合は(多重継承・仮想継承が絡むと細かいことが色々あるが、
それを忘れれば)何も起こらない。

class Base {};
class Deriv : public Base {}
Base* pb = new Deriv;  // OK

特に Base に仮想関数が定義してある場合、pb 経由で仮想関数を呼び出すと
Deriv の関数が呼ばれる。

class Base { public: virtual void foo(); };
class Deriv { public: virtual void foo(); };
Base* pb = new Deriv;
pb->foo();  // Base::foo() ではなく Deriv::foo() が呼ばれる

逆に基底クラスから派生クラスにキャストするのは、実体の場合には論外。ポインタ・
参照の場合には「実はそのポインタ・参照は派生クラスを指している」という場合に限っ
て OK。そうでない場合には、直後にメモリ領域壊すことになる。

Base* pb = new Deriv;
Drive* pd = static_cast<Deriv*>(pb); // OK

Base* pb = new Base;
Deriv* pd = static_cast<Deriv*>(pb); // コンパイルは通るが、直後に惨状が待ち受けてる

っつか、基本事項だから「プログラミング言語 C++」でも買ってきて読んどけ。一から
十まで説明してたら 1 スレ使っても字数が足りんよ。
0697デフォルトの名無しさんNGNG
>>666
>> なんでわざわざそんな不要なコード書きたがるかね
>これ、コボラーの発想だよ。
 
余計なコードを書かないってのは言語を超えた開発の鉄則。
新規コードは最小限に抑えるべし。
念のために言っておくが、変数・関数名を短くしろとか、
改行を惜しめって意味じゃないからね。
 
無論ひまつぶし等は別だが、その場合はその旨を明記して欲しい。
0698デフォルトの名無しさんNGNG
>>697
一人の人も救えないのに世界を救えるはずがないよな!
0699デフォルトの名無しさんNGNG
>>698
んなこたーない
0700698NGNG
>>699
知ってる
0701デフォルトの名無しさんNGNG
>>683
言語に純仮想関数の機構(late binding)があると、
オブジェクト指向プログラミングができるようになる。
0702デフォルトの名無しさんNGNG
>>701
・・・・・単なる仮想関数でもそうでしょ?
0703デフォルトの名無しさんNGNG
>>701 >>702
うむ。その通りだ。VBもオブジェクト指向プログラミングはできるのだよ。
0704デフォルトの名無しさんNGNG
>>701-703
それは仮想ではなく妄想ではないかと・・・
0705デフォルトの名無しさんNGNG
>>704
あなたこそ妄想です。
0706デフォルトの名無しさんNGNG
ポリモーフィズムできりゃOOPはできる。
(向き不向き存在価値なしはあるにしても)
0707デフォルトの名無しさんNGNG
「オブジェクト指向=多態」と思い込んでいる馬鹿がいるな
0708デフォルトの名無しさんNGNG
typedef aiueo *kakikukeko;

ってのがよく分かりません。

typedef aiueo* kakikukeko;

のことですか?
0709デフォルトの名無しさんNGNG
ソーデース
0710デフォルトの名無しさんNGNG
>>703
そらそーだ
ただ、金属バットで家建てようとしているようなもんだけどな
0711デフォルトの名無しさんNGNG
//文字列でNULLがないときってやばくない?
struct OOO
{
char c[4];
char j;
};
#include<iostream>
#include<string>
#define print(x) std::cout << (x) <<std::endl;
int main()
{
OOO nn = {'3','3','3','3',22};
print( sizeof( nn.c ) );//4
print( strlen( nn.c ) );//11
std::string BadStr= nn.c;
print( BadStr );//3333???????
std::string TrueStr = BadStr.substr(0,(strlen(nn.c) > sizeof(nn.c) ? sizeof(nn.c) : strlen(nn.c)));
print( TrueStr );//3333
}
0712デフォルトの名無しさんNGNG
>>708
kakukikeko は aiueo へのポインタってこと。
aiueo を *kakikukeko であらわせるなら、
&aiueo は kakikukeko でしょ?

aiueo a;
kakukikeko k;
k = &a;
0713デフォルトの名無しさんNGNG
>>711
当たり前だろ。
0714666NGNG
>>697
> 余計なコードを書かないってのは言語を超えた開発の鉄則。

    ま た Y A G N I か
0715デフォルトの名無しさんNGNG
クラスローカルな定数って定義できます?
class MyClass{
 const int err = 1;
}
はできませんでした。
0716デフォルトの名無しさんNGNG
>>715
こういうのはどう鐘。

class MyClass{
 static const int err;
}
const int MyClass::err = 1;
0717デフォルトの名無しさんNGNG
>>715
enum使っとけ。
0718デフォルトの名無しさんNGNG
class MyClass{
 static const int err = 1;
}
なら可能(整数だけだが)。できないコンパイラはヘタレ。
0719デフォルトの名無しさんNGNG
>>714
つまり、度々無駄なコードを書いては先輩や上司から叱責されていると?
0720デフォルトの名無しさんNGNG
>>715
確かにえなーむが妥当
0721デフォルトの名無しさんNGNG
class MyClass{
 const int err;
}

MyClass::MyClass() : err(1) {
}
0722デフォルトの名無しさんNGNG
セミコロンを忘れずに・・・
0723721NGNG
>>722
正直、すまんかった。
浮気性なもんでJava子や#子の癖が出るんでね。

class MyClass{
 const int err;
};

MyClass:MyClass() : err(1){
}
0724デフォルトの名無しさんNGNG
>>723
こんどはコロンが一つ…
0725デフォルトの名無しさんNGNG
コンロも一つ
0726デフォルトの名無しさんNGNG
蝉を退治する殺虫剤で「セミコロン」とか作ったら面白いよね。
0727デフォルトの名無しさんNGNG
(゚Д゚)ハァ?
0728328NGNG
>>726
オレはオマエのほうが面白いと思うがどうか。
0729デフォルトの名無しさんNGNG
328 は意味不明だが、728 には同意
0730デフォルトの名無しさんNGNG
随分と突飛だな。
0731デフォルトの名無しさんNGNG
>>728
面白いというかおっぱいしゃぶりたいよね。
0732デフォルトの名無しさんNGNG
void* から非void型への変換のキャストって???
0733デフォルトの名無しさんNGNG
???
0734デフォルトの名無しさんNGNG
>>732
何がいいたいのかサパーリわからん。

template<typename T>
T void_ptr_to_hoge(void* p)
{
 return reinterpret_cast<T>(p);
}

↑でいいのか?
0735デフォルトの名無しさんNGNG
void* は非 void 型だよな
0736デフォルトの名無しさんNGNG
borland C++ 使ってるんですが
マルチスレッド化のやり方がわかりません。
教えてください 頼みます
0737デフォルトの名無しさんNGNG
>>736
WindowsならWin32APIのCreateThreadでいいんじゃない?
0738デフォルトの名無しさんNGNG
猫を呼んで来い
0739デフォルトの名無しさんNGNG
 =⊂(ΦωΦ)⊃

呼んで来ました!
0740デフォルトの名無しさんNGNG
。 猫じゃないものがキタぁぁぁぁ!!
。   ∧_∧。゚
 ゚  (゚ ´Д`゚ )っ゚
  (つ   /  アァァァァ
    |  (⌒)
   し⌒^
0741デフォルトの名無しさんNGNG
>>734
static_castじゃないんか?
0742デフォルトの名無しさんNGNG
static_cast でいいのか?
reinterpret_cast のが妥当だと思うが・・・。
0743デフォルトの名無しさんNGNG
reinterpret_castだよ。
0744デフォルトの名無しさんNGNG
C++で作成したアプリケーションについてですが
Spy++とかで確認することができる
クラス名があるじゃないですか。
あれはバイナリ(exe)にはどんな風にして格納されてるんでしょうか?

やりたいことはメインウィンドウのクラス名を
バイナリエディタで書き換えたいのです。

よろしくおながいします(´・ω・`)
0745デフォルトの名無しさんNGNG
> Spy++とかで確認することができる
> クラス名があるじゃないですか。

・・・え?
もしかして、ウィンドウクラスの事?
ならスレ違いと言っておこう。
0746デフォルトの名無しさんNGNG
>>745
すれ違いでしたか(´-ω-`;)
C++で作られたプログラムということだったので
こちらで質問してしまいました。ごめんなさいです。
もしよかったらどこのスレッドで聞けば
答えてもらえるのかだけでも教えてもらえませんでしょうか。
ほんとすいません・・・。
0747デフォルトの名無しさんNGNG
C++ で作られたプログラムだろうが、C++ の事について訊きたいのでなければ
スレ違い。
妥当なのはぱっと思いつかないけど、近そうなのは Win32API スレ、Windows
Programing スレあたりか。
0748デフォルトの名無しさんNGNG
>>747
ありがとうございますです。
さっそくそちらのほうに尋ねてみたいと思いまつ(´・ω・`)
0749デフォルトの名無しさんNGNG
class Baka
{
friend ostream& operator<<(ostream& os, const Baka& obj);
private:
int aho;
};

として、cppファイルのほうでoperator<<のほうを実装すると、
この関数は、privateにアクセスでききない。と出ます。

クラス宣言の中で、インラインで書いてやると、コンパイル通ります。
コンパイラはVS.NETを使っているのですが、コンパイラの仕様ですか?
何か間違っているのでしょうか?
0750デフォルトの名無しさんNGNG
>>749
classのデフォルトのアクセス権はprivateです。
0751デフォルトの名無しさんNGNG
d2fc22-022.tiki.ne.jp
0752デフォルトの名無しさんNGNG
>>749
> 何か間違っているのでしょうか?
お前の関数の書き方。
0753デフォルトの名無しさんNGNG
>>749
その .cpp での実装もさらせ。
0754デフォルトの名無しさんNGNG
>>749
普通に通るけど何か問題でも?

class Baka
{
friend std::ostream& operator<<(std::ostream& os, const Baka& obj);
int aho;
public:
Baka(int i) : aho(i) {}
};

std::ostream& operator<<(std::ostream& os, const Baka& obj)
{
os << obj.aho;
return os;
}

int main()
{
Baka b(123);

std::cout << b << std::endl;
}
0755デフォルトの名無しさんNGNG
friend ostream& operator<<(ostream& os, const Baka& obj);
がprivateだから外からアクセスできないってことだろ。

あ た り ま え だ ボ ケ
0756デフォルトの名無しさんNGNG
>>755
(゚Д゚)ハァ?friend宣言はメンバじゃないよ。
0757749NGNG
>754
全く同じ様にしてるのですが、
できないんです。何故だろう。

os << obj.aho;

の部分がエラーになります。

因みに、friend関数をpublicにしようが、
privateにしようが同じです。
0758デフォルトの名無しさんNGNG
>>757
「全く同じ様にしてる」ってコピペしてみればいいかも・・・
0759デフォルトの名無しさんNGNG
同じよ同じ。でもちょっとだけ同じじゃないの。
0760デフォルトの名無しさんNGNG
>>759
全コードを載せてくれ。
0761デフォルトの名無しさんNGNG
>>757
friendは宣言だけなんだから、privateにしようがpublicにしようが関係ない。
gcc3.2.1(MinGW)では問題なく通ったぞ。
0762749NGNG
>758
すいません。コピペしてみて試してみました。
なんと、コンパイル通りました。
よく見てみると、全く同じでは内容です。

baka.hで

namespace Orokamono
{
class Baka
{
friend std::ostream& operator<<(std::ostream& os, const Baka& obj);
int aho;
public:
Baka(int i) : aho(i) {}
};
}

baka.cppで

#include <iostream>
#include "baka.h"
using namespace std;
using namespace Orokamono;
std::ostream& operator<<(std::ostream& os, const Baka& obj)
{
os << obj.aho;
return os;
}

とやると、フレンド関数がクラスのprivateメンバにアクセスできなくなります。
これは、書き方がおかしいのでしょうか?
0763749NGNG
自己解決しました。ありがとうございます。
どうやら

baka.cppで

ostream& Orokamono::operator<<(ostream& os, const Baka& obj)
{
・・・
}

としたら、できるようです。
これって、標準の正しい書き方ですか?
名前空間をusingしているのにこの書き方はおかしい気がします。
0764デフォルトの名無しさんNGNG
>>762
こうやったら通ったぞ。

std::ostream& Orokamono::operator<<(std::ostream& os, const Baka& obj)
{
os << obj.aho;
return os;
}
0765デフォルトの名無しさんNGNG
>>763
定義する識別子にはusingは関係ない。
0766デフォルトの名無しさんNGNG
>>763
<<演算子そのものもOrokamono名前空間で包んでおかないとだめなのでは?
0767デフォルトの名無しさんNGNG
例えば、
namespace Orokamono {
class Baka {
friend std::ostream& ::operator<<(std::ostream& os, const Baka& obj);
int aho;
public:
Baka(int i) : aho(i) {}
};
}
のような書き方が意味を持つならば(<<がOrokamonoの外にある事を示す)、
<<の定義部ではOrokamono限定子は不要だったろうが、いろいろ試してみたが、
名前空間の外にあるという指示を出すことは出来ないようだ。
0768749NGNG
名前空間の中にある、クラスの中で
friendの宣言をしているだけで、その関数は名前空間の中で
宣言されてるってことなのでしょうか。

別の名前空間にある関数をfriendにするってこともできなくなるのでは?
0769デフォルトの名無しさんNGNG
>>767
できないんだ?
それは困ったね・・・
0770デフォルトの名無しさんNGNG
>>768>>769
どうも、friendと名前空間は相性が悪いようです。混ぜて使わない方が
良さそうです。
0771デフォルトの名無しさんNGNG
>>770
んなこたーない
0772デフォルトの名無しさんNGNG
>>771
でも、いろいろやってみたけど、他の名前空間に含まれる関数をfriendに
できなかったよ。何か方法あるの?
0773デフォルトの名無しさんNGNG
>772
前方宣言しとけば良いだけでは?

namespace NS { void func(); }

class Foo
{
 ...
 friend void NS::func();
};
0774デフォルトの名無しさんNGNG
>>773
おお!うまく行った!しかし、operator<<の名前空間の解決のためにかなり
おかしな書き方をしなければならんようです。何とかならないものか?

-- baka2.h

namespace Orokamono {
class Baka;
}

namespace Hentai {
std::ostream& operator<<(std::ostream& os, const Orokamono::Baka& obj);
}

namespace Orokamono {
class Baka {
friend std::ostream& Hentai::operator<<(std::ostream& os, const Baka& obj);
int aho;
public:
Baka(int i) : aho(i) {}
};
}
0775デフォルトの名無しさんNGNG
続き
-- baka2.cpp

#include <iostream>
#include "baka2.h"

namespace Hentai {
std::ostream& operator<<(std::ostream& os, const Orokamono::Baka& obj)
{
os << obj.aho;
return os;
}
};

int main()
{
Orokamono::Baka b(123);

Hentai::operator<<(std::cout, b) << std::endl; //これが嫌らしい。何とかならんか?
}
0776デフォルトの名無しさんNGNG
int main()
{
using Hentai::operator<<;

Orokamono::Baka b(123);

std::cout << b << std::endl;
}

のように、こういう時こそusing宣言が役に立ちそうだ。
0777デフォルトの名無しさんNGNG
えーと、議論してる皆さん、Exceptional C++読みなさい。
要点は
・friend関数はclassの構成要素の一部である
 (したがって同じヘッダファイル・同じ名前空間に入れるべきである)
・同じ名前空間にあれば、koenigの名前照合規則が適用される
0778デフォルトの名無しさんNGNG
こんな感じ?

namespace Orokamono {
class Baka {
int i;
friend void print(Baka& b);
public:
Baka(int j) : i(j) {}
};
void print(Baka& b)
{
std::cout << b.i << std::endl;
}
}

void wrapper(Orokamono::Baka& b)
{
print(b); // Koenig lookup
}

int main()
{
Orokamono::Baka b(123);
wrapper(b);
}
0779デフォルトの名無しさんNGNG
もう一つわかっちまった。

int main()
{
Orokamono::Baka b(123);

std::cout << b << std::endl;
}

が動かないのは、operator<<と、bが違う名前空間に属しているため、
koenig名前照合が働かないからだね。この例では、friend宣言した<<
演算子は、bと同じ名前空間に入れてKoenig名前照合が働くようにす
るのがスマートな解決法だと言えるね。
0780デフォルトの名無しさんNGNG
>この例では、friend宣言した<<演算子は、bと同じ名前空間に入れてKoenig名前照合が働くようにする

そう、それを言いたかったの。

それと、>>778はwrapperかまさなくても、main中で直接print(b)と書けるよ。
koenig則のおかげで。
それがprintでなく、operator<<だとしても同じこと。
0781デフォルトの名無しさんNGNG
>>780
ありがとうー!おかげで名前空間に関する理解が深まりました。
friendが名前空間をまたぐことができるという仕様はそのままにして
おいて、スマートにKoenig則が働くよう、無意味に名前空間を
またぐようなプログラムは書かない方がいいみたいですね。
0782デフォルトの名無しさんNGNG
C++はIEEEされてますか?
0783デフォルトの名無しさんNGNG
yes, C++ was IEEEd.
0784デフォルトの名無しさんNGNG
struct SA{
struct {int nn;}NN;
SA():NN.nn(NULL){}
};
なんでコンストラクタで初期化できないんだろう?
SA(){NN.nn=0;}
は、うまくいくのに。
■ このスレッドは過去ログ倉庫に格納されています