2017-01-05 47 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()),钱存在银行里,但我不能。我可以使用struct Impl和unique_ptr来进行培训。 我知道,那独特的不能复制。 我该如何制作这个程序? 我的其他代码是否正常?

错误

错误C2027使用未定义类型 '银行:: PropertiesBank' 错误的
C2039 '的returnValue':不是 '的std ::的unique_ptr>'

+2

当你说你“不能”时,你是什么意思?你有构建错误吗?运行时错误或崩溃?意外的结果?请详细说明!并请[请阅读如何提出良好问题](http://stackoverflow.com/help/how-to-ask)。 –

+1

由于您想在类外定义'PropertiesBank',因此您需要定义将它用于类之外的函数:其实现必须位于结构定义之后。随着这种变化,[你的代码编译](http://rextester.com/UVFJ63318) –

+1

啊,建立错误。然后编辑你的问题,包括编译器的* full *和* complete *和* unnedited *输出。在构建到问题主体时,只需将输出复制粘贴为文本即可。 –

回答

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)) {}; 
}; 

你应该动函数的定义后,其中编译器已经看到了类型的​​定义:

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

但构造Bank后变量“k”具有相同的值。我的解决方案出了什么问题?我想,如果我把钱移到银行,那钱就没有价值。我是对的? – 21koizyd

+1

@ 21koizyd ...当你从一个对象,*** ***和另一个对象或函数,*** B ***通过一个* rvalue *引用抓取它时。 *** A ***的状态完全取决于*** B ***决定如何处理它。所以移动后的'Money'状态取决于你对移动构造函数做了什么。顺便说一句...在原代码的'int main()'中,你没有将'std :: move' * k *转换成* bank * ....另请参见[this](http:// stackoverflow.com/questions/14679605/do-built-in-types-have-move-semantics)(特别是在接受的答案的最后一句话) – WhiZTiM

+0

奥基,我正在考虑这种可能性:)。所以,谢谢:) – 21koizyd

2

我能看到的唯一问题是,012的定义尝试访问Bank::PropertiesBank时,它只是前向声明,未定义。移动PropertiesBank定义在Bank倾斜内修复此问题。

然而,随着鸣叫鸭子在评论中指出的,如果你的目的是要实现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

这是真的。回答修改以记录这一点。 –