2017-01-05 11 views
0

を移動:コンストラクタは、私は、コードを持っている

#include "stdafx.h" 
#include "memory" 
#include <gtest\gtest.h> 
class Money 
{ 
public: 
    explicit Money(int value) :value(value) {} ; 
    Money(Money&& m) :value(m.returnValue()) {}; 
    Money(const Money &m) = default; 
    Money operator-(const Money &m) ; 
    Money &operator=(Money &&m) { return Money(m.returnValue()); }; 
    Money &operator=(const Money &m)=default; 
    int returnValue() const { return value; }; 
    ~Money() = default; 
private: 
    int value; 
}; 
Money Money::operator-(const Money &m) 
{ 
    return Money(value - m.returnValue()); 
} 


class Bank { 
public: 
    Bank(Money m) :propertiesBank(std::make_unique<PropertiesBank>(std::move(m))) {}; 
    int returnMoney() const { return propertiesBank->money->returnValue(); } 
    ~Bank() = default; 
private: 
    struct PropertiesBank; 
    std::unique_ptr<PropertiesBank> propertiesBank; 
}; 

struct Bank::PropertiesBank 
{ 
    std::shared_ptr<Money> money; 
    PropertiesBank(Money&& m) :money(std::make_shared<Money>(m)) {}; 
}; 
int main() 
{ 
    Money k(1000); 
    Bank bank(k); 
    return 0; 
} 

を私は銀行で表示(returnMoney())お金が欲しい、私はできません。私は訓練のために構造体Implとunique_ptrでクラスを作ることができました。 私は知っている、ユニークなコピーすることはできません。 どうすればこのプログラムを作成できますか? 残りのコードは正常ですか?

未定義の型 '銀行:: PropertiesBank' エラー
C2039 'のreturnValue' の

エラーC2027を使用

エラー:のメンバーではありません 'のstd :: unique_ptrを>'

+2

あなたが「できない」と言うとき、それはどういう意味ですか?ビルドエラーが出ますか?実行時エラーまたはクラッシュ予想外の結果ですか?詳しく教えてください!また、[良い質問をする方法について](http://stackoverflow.com/help/how-to-ask)もお読みください。 –

+1

あなたはクラスの外に 'PropertiesBank'を定義したいので、あなたも、クラスの外にそれを使用する関数を定義する必要があります。その実装は、構造体の定義の後にする必要があります。その変更で、[あなたのコードはコンパイル](http://rextester.com/UVFJ63318) –

+1

ああ、ビルドのエラー。次に、質問を編集して、コンパイラの* full *と* complete *と* unedited *出力を含めます。質問本体にテキストとして作成すると、出力をコピーして貼り付けるだけです。 –

答えて

1

そのstd::unique_ptrでない問題、あなたはタイプコンパイラはその完全な定義を見ていないときPropertiesBankであるオブジェクトのメンバにアクセスしようとしたこと、その事実。あなたはクラスの外とコンパイラがPropertiesBankの完全な定義を見てきた時点で、メンバ関数の定義を移動する必要があります。

以下このスニペットにコメントを参照してください:

class Bank { 
public: 
    Bank(Money m) :propertiesBank(std::make_unique<PropertiesBank>(std::move(m))) {}; 

    int returnMoney() const;{ return propertiesBank->money->returnValue(); } 
    // .......The compiler doesn't know that `money`^^^^^^ belongs to `PropertiesBank` 

    ~Bank() = default; 
private: 
    struct PropertiesBank; 
    std::unique_ptr<PropertiesBank> propertiesBank; 
}; 

struct Bank::PropertiesBank 
{ 
    std::shared_ptr<Money> money; 
    PropertiesBank(Money&& m) :money(std::make_shared<Money>(m)) {}; 
}; 

あなたは移動する必要があります私が見ることができる唯一の問題は、012の定義ということです

class Bank { 
public: 
    Bank(Money m) :propertiesBank(std::make_unique<PropertiesBank>(std::move(m))) {}; 
    int returnMoney() const; //member function declaration 
    ~Bank() = default; 
private: 
    struct PropertiesBank; 
    std::unique_ptr<PropertiesBank> propertiesBank; 
}; 

struct Bank::PropertiesBank 
{ 
    std::shared_ptr<Money> money; 
    PropertiesBank(Money&& m) :money(std::make_shared<Money>(m)) {}; 
}; 

//Member function's definition 
int Bank::returnMoney() const { return propertiesBank->money->returnValue(); } 
+0

しかし、変数 "k"は、Bankの後に同じ値を持ちます。私のソリューションで何が間違っていますか?私は、もし私がマネーを銀行に移すと、マネーは価値がないと思う。私は正しい? – 21koizyd

+1

@ 21koizyd ...あなた 'のstd ::オブジェクトからmove'、*** A ***と別のオブジェクトや関数は、*** Bは*** *の右辺値参照*を経由して、それをつかむとき。 *** A ***の状態は、どれも*** B ***がそれと関係があると決める。だから、それから移動した後の 'Money'の状態は、あなたが移動コンストラクタで行ったことに依存します。そして、ちなみに...元のコードの 'int main()'では、 'std :: move' * k *を* bank *にしませんでした。[this](http:// stackoverflow.com/questions/14679605/do-built-in-types-have-move-semantics)(特に最後の文のn受理応答) – WhiZTiM

+0

オーケー、私はこの可能性について考えていた:)。だから、ありがとう:) – 21koizyd

2

:コンパイラはタイプ​​のの定義を見ているところの後に関数の定義は、前方宣言されただけで定義されていない場合は、Bank::PropertiesBankにアクセスしようとします。移動PropertiesBankBankの範囲内で傾斜を定義してこれを修正します。 Mooingダックはコメントで指摘するように、あなたの意図がpImpl idiomを実装する場合

はしかし、その後、Bank::PropertiesBankBank::returnMoneyの両方ではなく、クラス定義内より、.cppファイルで定義する必要があります。

#include <memory> 

class Money 
{ 
public: 
    explicit Money(int value) :value(value) {} ; 
    Money(Money&& m) :value(m.returnValue()) {}; 
    Money(const Money &m) = default; 
    Money operator-(const Money &m) ; 
    Money operator==(Money &&m) { return Money(m.returnValue()); }; 
    int returnValue() const { return value; }; 
    ~Money() = default; 
private: 
    int value; 
}; 

Money Money::operator-(const Money &m) 
{ 
    return Money(value - m.returnValue()); 
} 

class Bank { 
public: 
    Bank(Money m) :propertiesBank(std::make_unique<PropertiesBank>(std::move(m))) {}; 
    int returnMoney() const { return propertiesBank->money->returnValue(); } 
    ~Bank() = default; 
private: 
    struct PropertiesBank 
    { 
     std::shared_ptr<Money> money; 
     int returnMoney() const { return money->returnValue(); } 
     PropertiesBank(Money&& m) :money(std::make_shared<Money>(m)) {}; 
    }; 

    std::unique_ptr<PropertiesBank> propertiesBank; 
}; 

#include <iostream> 

int main() 
{ 
    Money m(10); 
    Bank b(m); 

    std::cout << b.returnMoney(); 
    return 0; 
} 
+1

[pImpl](http://stackoverflow.com/questions/60570/why-should-the-pimpl-idiom-be-used)の意図に違反しています。正解は 'returnMoney'の定義を移動することです –

+0

それは本当です。これをメモするために回答が修正されました。 –

関連する問題