构造函数移动

时间:2017-01-05 00:18:40

标签: c++ c++11 move

我有一个代码:

#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使用未定义类型'Bank :: PropertiesBank'错误
  C2039'returnValue':不是'std :: unique_ptr&gt;'

的成员

2 个答案:

答案 0 :(得分:2)

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

然而,正如Mooing Duck在评论中指出的那样,如果您打算实施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 :(得分: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)) {};
};

您应该将函数的定义移到编译器已经看到propertiesBank类型的定义之后:

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