私のクラスNRRanNormal
は正規分布確率変数を表しています。デフォルトでは、インスタンスは平均 0 および stdev 1 (つまり、標準の正規確率変数) で正規分布されます。
オブジェクトをコピーNRRanNormal
すると、コピーされた (またはコピー コンストラクターを介して構築された) オブジェクトの平均値と標準偏差が文字化けしてナンセンスになることがあります。この文字化けの原因を見つけるのに苦労しています。
テスト目的で、次の関数は特定のNRRanNormal
オブジェクトの平均値と標準偏差を表示します。
void go(NRRanNormal& rv, const string label) {
std::cout << label << "\n"
<< "Mean: " << rv.getMean() << "\n"
<< "Stdev: " << rv.getStdev() << "\n\n";
}
それでは、次の 4 つのケースで何が起こるか見てみましょう。
NRRanNormal foo;
go(foo, "foo");
NRRanNormal bar1 = foo;
go(bar1, "bar1");
NRRanNormal bar2;
bar2 = foo;
go(bar2, "bar2");
NRRanNormal bar3(foo);
go(bar3, "bar3");
上記のステートメントの出力は次のとおりです。
foo
Mean: 0
Stdev: 1
bar1
Mean: 5.55633e-317
Stdev: 6.95332e-310
bar2
Mean: 0
Stdev: 1
bar3
Mean: 0
Stdev: 0
ご覧のとおり、オブジェクト ( foo
) をインスタンス化するだけで、期待どおりに機能します。
今、私がするときNRRanNormal bar1 = foo;
、オブジェクトbar1
は文字化けしています。しかし、私が行うNRRanNormal bar2; bar2 = foo;
と、オブジェクトbar2
は文字化けしません。これは私を困惑させます。のようなステートメントブロックだと思いました
MyClass A;
MyClass B = A;
コンパイラによって実際にステートメントブロックに変換されます
MyClass A;
MyClass B;
B = A;
したがって、すぐ上に書いたことが間違っていない限り、bar1
とはまったく同じメンバー値bar2
を持つ必要があるようです。しかし、上に貼り付けた出力からわかるように、文字化けしていますが、問題ありません。 bar1
bar2
どうすればいいの?
bar3
文字化けしていることにも気付くでしょう。これが同じ問題なのか、別の問題なのかわかりません。
のインターフェースと実装の簡略化されたバージョンを次に示しますNRRanNormal
。
class NRRanNormal {
public:
NRRanNormal();
~NRRanNormal();
NRRanNormal(const NRRanNormal& nrran);
NRRanNormal& operator= (const NRRanNormal& nrran);
double getMean() const;
double getStdev() const;
long getSeed() const;
private:
double m_mean, m_stdev;
long m_seed;
Normaldev* stream; // underlying C struct RN generator
};
NRRanNormal::NRRanNormal() { // by default, N(0,1)
m_mean = 0.0;
m_stdev = 1.0;
m_seed = 12345L;
stream = new Normaldev(m_mean, m_stdev, m_seed);
}
NRRanNormal::~NRRanNormal() { delete stream; }
NRRanNormal::NRRanNormal(const NRRanNormal& nrran) {
stream = new Normaldev(nrran.getMean(),nrran.getStdev(),nrran.getSeed());
*stream = *(nrran.stream);
}
NRRanNormal& NRRanNormal::operator= (const NRRanNormal& nrran) {
if(this == &nrran)
return *this;
delete stream;
stream = new Normaldev(nrran.getMean(),nrran.getStdev(),nrran.getSeed());
*stream = *(nrran.stream);
return *this;
}
double NRRanNormal::getMean() const { return m_mean; }
double NRRanNormal::getStdev() const { return m_stdev; }
long NRRanNormal::getSeed() const { return m_seed; }
Normaldev
構造体は Numerical Recipes 3d Edition からのものです。
コピー代入演算子またはコピー コンストラクターに何か問題がありますか?
これはNormaldev
、独自の計算を取り除いたものです。
typedef double Doub;
typedef unsigned long long int Ullong;
typedef unsigned int Uint;
struct Ranq1 {
Ullong v;
Ranq1(Ullong j) : v(/* some long number here */) {
/* proprietary calculations here */
}
inline Ullong int64() {
/* proprietary calculations here */
}
inline Doub doub() { /* proprietary calculations here */ }
inline Uint int32() { return (Uint)int64(); }
};
struct Normaldev : Ranq1 {
Doub mu,sig;
Normaldev(Doub mmu, Doub ssig, Ullong i):
Ranq1(i), mu(mmu), sig(ssig){}
Doub dev() {
/* proprietary calculations here */
}
};