C++相談室 part13
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの引き篭もり
NGNGelegantなソースを目指してね。
( ^-゚).。o(きっと関連URLは >>2-5 辺りだよ)
0685デフォルトの名無しさん
NGNG今は串を変えて書いてるけど、プロキシ使ってる人は、まとめて規制食らっ
ちゃうよ。
0686683
NGNGありがとうございます。よく分かりました。
0687デフォルトの名無しさん
NGNG0688デフォルトの名無しさん
NGNG0689デフォルトの名無しさん
NGNGメンバ関数のグループ化と規格化
「○○対応をうたうクラスにはこんな関数セットを用意すること」
0690デフォルトの名無しさん
NGNG{
};
class B : public A
{
};
というのがあり、
A* boo(A* obj);
という関数なら、クラスAクラスBのどちらのオブジェクトもとれるのは分かるのですが、
A& boo(A& obj);
なら、Aしか引数,戻り値にすることはできませんか?
0691デフォルトの名無しさん
NGNGB b;
A& boo(A& obj)
{
return b;
}
main()
{
boo(b);
}
0692デフォルトの名無しさん
NGNGBもできます
自分で試すきないの?
0693690
NGNGA boo(A& obj)
{
B b = new B();
return b;
}
という場合に、bを返したら、どうなりますか?
外で
B b = (B)boo(obj);
みたいなのはできないんでしょうか?
0694デフォルトの名無しさん
NGNG0695デフォルトの名無しさん
NGNG0696デフォルトの名無しさん
NGNG実体を基底クラスにキャストするとオブジェクトのスライシング、派生クラス分の
オブジェクトが捨てられて基底クラスに詰め込まれる、が起きる。
ポインタ・参照の場合は(多重継承・仮想継承が絡むと細かいことが色々あるが、
それを忘れれば)何も起こらない。
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>> なんでわざわざそんな不要なコード書きたがるかね
>これ、コボラーの発想だよ。
余計なコードを書かないってのは言語を超えた開発の鉄則。
新規コードは最小限に抑えるべし。
念のために言っておくが、変数・関数名を短くしろとか、
改行を惜しめって意味じゃないからね。
無論ひまつぶし等は別だが、その場合はその旨を明記して欲しい。
0698デフォルトの名無しさん
NGNG一人の人も救えないのに世界を救えるはずがないよな!
0699デフォルトの名無しさん
NGNGんなこたーない
0701デフォルトの名無しさん
NGNG言語に純仮想関数の機構(late binding)があると、
オブジェクト指向プログラミングができるようになる。
0702デフォルトの名無しさん
NGNG・・・・・単なる仮想関数でもそうでしょ?
0703デフォルトの名無しさん
NGNGうむ。その通りだ。VBもオブジェクト指向プログラミングはできるのだよ。
0704デフォルトの名無しさん
NGNGそれは仮想ではなく妄想ではないかと・・・
0705デフォルトの名無しさん
NGNGあなたこそ妄想です。
0706デフォルトの名無しさん
NGNG(向き不向き存在価値なしはあるにしても)
0707デフォルトの名無しさん
NGNG0708デフォルトの名無しさん
NGNGってのがよく分かりません。
typedef aiueo* kakikukeko;
のことですか?
0709デフォルトの名無しさん
NGNG0710デフォルトの名無しさん
NGNGそらそーだ
ただ、金属バットで家建てようとしているようなもんだけどな
0711デフォルトの名無しさん
NGNGstruct 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デフォルトの名無しさん
NGNGkakukikeko は aiueo へのポインタってこと。
aiueo を *kakikukeko であらわせるなら、
&aiueo は kakikukeko でしょ?
aiueo a;
kakukikeko k;
k = &a;
0713デフォルトの名無しさん
NGNG当たり前だろ。
0715デフォルトの名無しさん
NGNGclass MyClass{
const int err = 1;
}
はできませんでした。
0716デフォルトの名無しさん
NGNGこういうのはどう鐘。
class MyClass{
static const int err;
}
const int MyClass::err = 1;
0717デフォルトの名無しさん
NGNGenum使っとけ。
0718デフォルトの名無しさん
NGNGstatic const int err = 1;
}
なら可能(整数だけだが)。できないコンパイラはヘタレ。
0719デフォルトの名無しさん
NGNGつまり、度々無駄なコードを書いては先輩や上司から叱責されていると?
0720デフォルトの名無しさん
NGNG確かにえなーむが妥当
0721デフォルトの名無しさん
NGNGconst int err;
}
MyClass::MyClass() : err(1) {
}
0722デフォルトの名無しさん
NGNG0723721
NGNG正直、すまんかった。
浮気性なもんでJava子や#子の癖が出るんでね。
class MyClass{
const int err;
};
MyClass:MyClass() : err(1){
}
0724デフォルトの名無しさん
NGNGこんどはコロンが一つ…
0725デフォルトの名無しさん
NGNG0726デフォルトの名無しさん
NGNG0727デフォルトの名無しさん
NGNG0729デフォルトの名無しさん
NGNG0730デフォルトの名無しさん
NGNG0731デフォルトの名無しさん
NGNG面白いというかおっぱいしゃぶりたいよね。
0732デフォルトの名無しさん
NGNG0733デフォルトの名無しさん
NGNG0734デフォルトの名無しさん
NGNG何がいいたいのかサパーリわからん。
template<typename T>
T void_ptr_to_hoge(void* p)
{
return reinterpret_cast<T>(p);
}
↑でいいのか?
0735デフォルトの名無しさん
NGNG0736デフォルトの名無しさん
NGNGマルチスレッド化のやり方がわかりません。
教えてください 頼みます
0737デフォルトの名無しさん
NGNGWindowsならWin32APIのCreateThreadでいいんじゃない?
0738デフォルトの名無しさん
NGNG0739デフォルトの名無しさん
NGNG呼んで来ました!
0740デフォルトの名無しさん
NGNG。 ∧_∧。゚
゚ (゚ ´Д`゚ )っ゚
(つ / アァァァァ
| (⌒)
し⌒^
0741デフォルトの名無しさん
NGNGstatic_castじゃないんか?
0742デフォルトの名無しさん
NGNGreinterpret_cast のが妥当だと思うが・・・。
0743デフォルトの名無しさん
NGNG0744デフォルトの名無しさん
NGNGSpy++とかで確認することができる
クラス名があるじゃないですか。
あれはバイナリ(exe)にはどんな風にして格納されてるんでしょうか?
やりたいことはメインウィンドウのクラス名を
バイナリエディタで書き換えたいのです。
よろしくおながいします(´・ω・`)
0745デフォルトの名無しさん
NGNG> クラス名があるじゃないですか。
・・・え?
もしかして、ウィンドウクラスの事?
ならスレ違いと言っておこう。
0746デフォルトの名無しさん
NGNGすれ違いでしたか(´-ω-`;)
C++で作られたプログラムということだったので
こちらで質問してしまいました。ごめんなさいです。
もしよかったらどこのスレッドで聞けば
答えてもらえるのかだけでも教えてもらえませんでしょうか。
ほんとすいません・・・。
0747デフォルトの名無しさん
NGNGスレ違い。
妥当なのはぱっと思いつかないけど、近そうなのは Win32API スレ、Windows
Programing スレあたりか。
0748デフォルトの名無しさん
NGNGありがとうございますです。
さっそくそちらのほうに尋ねてみたいと思いまつ(´・ω・`)
0749デフォルトの名無しさん
NGNG{
friend ostream& operator<<(ostream& os, const Baka& obj);
private:
int aho;
};
として、cppファイルのほうでoperator<<のほうを実装すると、
この関数は、privateにアクセスでききない。と出ます。
クラス宣言の中で、インラインで書いてやると、コンパイル通ります。
コンパイラはVS.NETを使っているのですが、コンパイラの仕様ですか?
何か間違っているのでしょうか?
0750デフォルトの名無しさん
NGNGclassのデフォルトのアクセス権はprivateです。
0751デフォルトの名無しさん
NGNG0752デフォルトの名無しさん
NGNG> 何か間違っているのでしょうか?
お前の関数の書き方。
0753デフォルトの名無しさん
NGNGその .cpp での実装もさらせ。
0754デフォルトの名無しさん
NGNG普通に通るけど何か問題でも?
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がprivateだから外からアクセスできないってことだろ。
あ た り ま え だ ボ ケ
0756デフォルトの名無しさん
NGNG(゚Д゚)ハァ?friend宣言はメンバじゃないよ。
0757749
NGNG全く同じ様にしてるのですが、
できないんです。何故だろう。
os << obj.aho;
の部分がエラーになります。
因みに、friend関数をpublicにしようが、
privateにしようが同じです。
0758デフォルトの名無しさん
NGNG「全く同じ様にしてる」ってコピペしてみればいいかも・・・
0759デフォルトの名無しさん
NGNG0760デフォルトの名無しさん
NGNG全コードを載せてくれ。
0761デフォルトの名無しさん
NGNGfriendは宣言だけなんだから、privateにしようがpublicにしようが関係ない。
gcc3.2.1(MinGW)では問題なく通ったぞ。
0762749
NGNGすいません。コピペしてみて試してみました。
なんと、コンパイル通りました。
よく見てみると、全く同じでは内容です。
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メンバにアクセスできなくなります。
これは、書き方がおかしいのでしょうか?
0763749
NGNGどうやら
baka.cppで
ostream& Orokamono::operator<<(ostream& os, const Baka& obj)
{
・・・
}
としたら、できるようです。
これって、標準の正しい書き方ですか?
名前空間をusingしているのにこの書き方はおかしい気がします。
0764デフォルトの名無しさん
NGNGこうやったら通ったぞ。
std::ostream& Orokamono::operator<<(std::ostream& os, const Baka& obj)
{
os << obj.aho;
return os;
}
0765デフォルトの名無しさん
NGNG定義する識別子にはusingは関係ない。
0766デフォルトの名無しさん
NGNG<<演算子そのものもOrokamono名前空間で包んでおかないとだめなのでは?
0767デフォルトの名無しさん
NGNGnamespace Orokamono {
class Baka {
friend std::ostream& ::operator<<(std::ostream& os, const Baka& obj);
int aho;
public:
Baka(int i) : aho(i) {}
};
}
のような書き方が意味を持つならば(<<がOrokamonoの外にある事を示す)、
<<の定義部ではOrokamono限定子は不要だったろうが、いろいろ試してみたが、
名前空間の外にあるという指示を出すことは出来ないようだ。
0768749
NGNGfriendの宣言をしているだけで、その関数は名前空間の中で
宣言されてるってことなのでしょうか。
別の名前空間にある関数をfriendにするってこともできなくなるのでは?
0769デフォルトの名無しさん
NGNGできないんだ?
それは困ったね・・・
0770デフォルトの名無しさん
NGNGどうも、friendと名前空間は相性が悪いようです。混ぜて使わない方が
良さそうです。
0771デフォルトの名無しさん
NGNGんなこたーない
0772デフォルトの名無しさん
NGNGでも、いろいろやってみたけど、他の名前空間に含まれる関数をfriendに
できなかったよ。何か方法あるの?
0773デフォルトの名無しさん
NGNG前方宣言しとけば良いだけでは?
namespace NS { void func(); }
class Foo
{
...
friend void NS::func();
};
0774デフォルトの名無しさん
NGNGおお!うまく行った!しかし、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{
using Hentai::operator<<;
Orokamono::Baka b(123);
std::cout << b << std::endl;
}
のように、こういう時こそusing宣言が役に立ちそうだ。
0777デフォルトの名無しさん
NGNG要点は
・friend関数はclassの構成要素の一部である
(したがって同じヘッダファイル・同じ名前空間に入れるべきである)
・同じ名前空間にあれば、koenigの名前照合規則が適用される
0778デフォルトの名無しさん
NGNGnamespace 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デフォルトの名無しさん
NGNGint main()
{
Orokamono::Baka b(123);
std::cout << b << std::endl;
}
が動かないのは、operator<<と、bが違う名前空間に属しているため、
koenig名前照合が働かないからだね。この例では、friend宣言した<<
演算子は、bと同じ名前空間に入れてKoenig名前照合が働くようにす
るのがスマートな解決法だと言えるね。
0780デフォルトの名無しさん
NGNGそう、それを言いたかったの。
それと、>>778はwrapperかまさなくても、main中で直接print(b)と書けるよ。
koenig則のおかげで。
それがprintでなく、operator<<だとしても同じこと。
0781デフォルトの名無しさん
NGNGありがとうー!おかげで名前空間に関する理解が深まりました。
friendが名前空間をまたぐことができるという仕様はそのままにして
おいて、スマートにKoenig則が働くよう、無意味に名前空間を
またぐようなプログラムは書かない方がいいみたいですね。
0782デフォルトの名無しさん
NGNG0783デフォルトの名無しさん
NGNG0784デフォルトの名無しさん
NGNGstruct {int nn;}NN;
SA():NN.nn(NULL){}
};
なんでコンストラクタで初期化できないんだろう?
SA(){NN.nn=0;}
は、うまくいくのに。
■ このスレッドは過去ログ倉庫に格納されています