c ++:您可以使用父构造函数初始化子类中的数据吗?

时间:2017-11-22 20:18:08

标签: c++ c++11

我试图找出是否可以使用由父类构造函数初始化的数据,然后使用它来填充子类向量。我一直在寻找这样的东西,但我最接近它的就是这里 Using the Parent constructor to initialize a child class,遗憾的是没有帮助。

我的父类看起来像这样

class Pile
{
protected:
    vector<int> cards;

public:
  Pile();

  vector<int> getCards();
  void shuffleDeck();
  void dealHand();

  void displayGame();
};

儿童班:

class Hand : public Pile
{
protected:
  deque<int> hand1;
};

它的实施:

#include "Declarations.h"
Pile::Pile()
{


  for(int i = 1;i <= 52; i++)
    cards.push_back(i);


  shuffleDeck();

  // What I would like to do.
  // dealHand();

}

理想情况下,我创建了一副牌,将它们洗牌,然后将它们交给他们需要的地方(子类)。我知道如何通过实例化子类,为它们创建方法,以及从父类传递向量来实现这一点,但这看起来很糟糕。

你能告诉我一种从Pile类向量中移动一个元素的方法&#39; card&#39;它的儿童班Hand's deque&#39; hand1&#39;没有实例化手?如果没有,是否有比我的后备更直接的方法?

2 个答案:

答案 0 :(得分:0)

SomeCards是一张卡片。

class SomeCards {
  std::vector<int> cards;
public:
  SomeCards( std::vector<int> cards_in = {} ):cards(std::move(cards_in)) {}
  std::vector<int> allCards() const { return cards; }
  void shuffleCards(); // TODO
  SomeCards drawCards(std::size_t count) {
    std::vector<int> r;
    for(std::size_t i = 0; i < count; ++i) {
      if (!cards.empty()) {
        r.push_back(cards.back());
        cards.pop_back();
      }
    }
    return r;
  }
  void addCards( SomeCards in ) {
    cards.insert( cards.end(), in.cards.begin(), in.cards.end() );
  }
};

Hand是一些具有额外功能的卡片。此外,我们希望阻止双手交易。

class Hand : private SomeCards
{
public:
  using SomeCards::allCards;
  using SomeCards::addCards;

  using SomeCards::SomeCards;
  // TODO more?
};

Deck也是一些具有额外功能的卡片:

class Deck : private SomeCards
{
public:
  using SomeCards::SomeCards;
  using SomeCards::shuffleCards;
  Hand drawHand(std::size_t size) {
    return drawCards(size);
  }
  std::vector<Hand> drawHands(std::size_t count, std::size_t size) {
    std::vector<Hand> r;
    r.reserve(count);
    for (std::size_t i = 0; i < count; ++i)
      r.push_back( drawHand(size) );
    return r;
  }
  std::size_t drawTo( Hand& hand, std::size_t count ) {
    auto cards = drawCards(count);
    hand.addCards( cards );
    return cards.size();
  }
};

然后我们建立一个游戏:

class Game {
  Deck deck;
  std::vector<Hand> hands;
public:
  // TODO
};

注意SomeCards是继承的,但私下里,因为我对其进行了常规操作(不能识别卡片的内容),而我正在使用using SomeCards::operation将它们注入私人孩子。

可互换地处理甲板和手是值得怀疑的。

我们还可以从SomeCards中删除非常用功能并公开继承。

这种设计开辟了一种可能性,你可以编写一个简单的OrderedHand,其行为与Hand非常相似,但改组是有道理的。

我没有太多尝试避免上面的不必要的副本。

答案 1 :(得分:0)

基类构造函数在派生类成员初始化之前运行。因此,它只能修改那些成员,如果他们有简单的初始化;否则,在成员生命开始之前使用成员将是未定义的行为。

我建议您以不同的方式设计您的课程以避免这种需要。