【问题标题】:Auto and reference自动和参考
【发布时间】:2018-02-04 11:59:21
【问题描述】:

我有以下课程:

class Card {
    void rotate();
};
class Type1Card : public Card {};
class Type2Card : public Card {};

class Deck {
    Card& draw_card();
};

class Board {
    std::vector<Card const*> cards;
    void put_card(Card const&);
};

所以套牌管理卡片。它返回一张卡片的reference。然后可以将一张卡片放在板上 - 使用 const reference 表示它不能是nullptr 也不能更改。如您所见,Board 存储指向卡片的指针(由于多态化)。

有问题的代码:

auto card = deck.draw_card(); // a copy of a card is created
card.rotate();
board.put_card(card); // board will get a pointer to a temporary variable

我看到的解决方案:

  1. draw_card 返回一个指针 - 丑陋,因为我相信那个指针 是表示可以返回nullptr - 不正确
  2. put_card 得到一个指针 - 为什么不和上面一样
  3. 禁用 Card 的复制构造函数 - 丑陋,因为这不是 Card 的问题 - 没有理由限制 Card 类

【问题讨论】:

  • 你要auto&amp;吗?
  • 你真的需要多态卡吗?这似乎是一个奇怪的设计......
  • 我想我需要。我想放尽可能少的代码。但是在甲板上我有更多类型的牌(一些行动牌,不能放在板上)。而且我认为只有一种类型的卡片会使它有很多未使用的字段并且过于复杂。
  • 我不认为这是一个好的设计。我不知道你的游戏规则,但通常情况下,一个操作应该做的不是单张牌,而是多张牌的组合。您当前的设计将不可避免地让您陷入 dynamic_casttypeid 的大混乱,无论您有两个或更多 Card&amp;s 并且需要决定适用于它们的游戏规则。

标签: c++ pointers reference


【解决方案1】:

你可以告诉auto变量是引用,直接写

auto& card = deck.draw_card();

const 引用相同

const auto& card = deck.draw_card();

【讨论】:

  • 好的。这会有所帮助。我对这个(我的意思是我的)解决方案只有一个担心:界面用户需要知道draw_card 返回一个引用并且put_card 需要一个有效地址。你认为这是一个好的设计......?
  • @user2146414 - 用户不需要知道。他们的编译器会告诉他们你是否正确设计了你的类。
  • @StoryTeller 但在我的例子中,他使用auto card = ... 编译器并没有告诉他有什么问题。使用auto&amp; card = ... 是正确的,但需要注意draw_cardput_card
  • @user2146414 - 因为没有什么错的。您没有禁止制作副本,因此不会阻止用户复制。就像我说的“如果你正确地设计你的课程”
  • @StoryTeller 你认为删除 Card 的复制构造函数会是“一个设计合理的类”吗?正如您在我帖子的第 3 点中看到的那样,我有一些疑问。但我很好奇你的意见。
【解决方案2】:

auto&amp;就够了:

auto& card = deck.draw_card();

所以在类型推断期间不会丢弃引用。


另外,请注意,使用 std::vector 的原始指针:

std::vector<Card const*> cards;

不是最好的主意。当您的卡片到达外部Board 时,Board 本身并不能控制它所引用的卡片的生命周期。在这种情况下,获取悬空指针并移动到 UB 区域非常容易。

您可能应该考虑将卡片复制到Board 类或开始使用智能指针 - 任何更适合您的程序的方法。

【讨论】:

  • 我认为您关于存储指针的评论是必不可少的。不控制卡寿命的情况是故意的。我希望套牌能够控制卡牌的寿命。我故意传递了一个引用(原始指针)作为不拥有“指针”的指标。所以也许复制一张卡片会是一个更好的选择......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多