如何获取 C++ 类成员向量的大小?

Posted

技术标签:

【中文标题】如何获取 C++ 类成员向量的大小?【英文标题】:How to get the size of a c++ class member vector? 【发布时间】:2014-08-05 15:50:30 【问题描述】:

我有一个具有std::vector 类型成员的类。在某些地方,我需要另一个类中该向量的大小。因为该成员是私有的,所以我创建了一个 getter 来返回它。在查看代码时,我想到了一个问题:调用 getter 然后是 size() 更好还是创建一个“size getter”更好?

这是我的课:

class MyClass

private:
  std::vector< int > m_myVec;

public:
  std::vector< int > getMyVec() const  return m_myVec; 
  // Shall I create:
  // std::size_t getMyVecSize() const  return m_myVec.size(); 

  // ... other function
;

在我做的代码的其他部分:

std::size_t sz = myClsObj.getMyVec().size(); // or
if (myClsObj.getMyVec().size() > 5)  /*...*/ 

这样做是一个好习惯,还是我将创建并调用“size getter”?


我需要向量(在代码的其他部分我称为 getter)和它的大小;所以没有必要选择只保留一个吸气剂。

另一个事实是我使用的是 C++11,所以不需要返回 const 引用。

基于C++11:如果我调用myClsObj.getMyVec().size(),不返回向量而是返回它的大小是不是很聪明?

【问题讨论】:

我个人会使用vector getter,但是让它返回一个引用以避免复制。 你喜欢复制向量以获得它们的大小然后扔掉副本吗?您认为这种活动是否让您来之不易的 gigaflops 得到了充分利用?也许复制宇宙以计算此评论副本中的字符数是一个好的设计决策? @Fsmv 对此表示强烈反对。 @Fsmv 指的是返回一个局部变量,而不是类成员。 @Fsmv 即使那是正确的,“编译器非常聪明,它会弥补我的愚蠢”也不能成为违反基本编码实践的借口。 【参考方案1】:

可以参考Tell Don't Ask原理。这里可能有点令人困惑,因为这两个版本在技术上都在“要求”某些东西。但重点不是使用 getter 来检索类的实现细节,然后对其执行一些操作,而是 告诉 类完成所需的工作,在这种情况下是 - 检索大小.

这也与Law of Demeter 有关。返回整个向量的方法在此链接中以一种很棒的方式可视化,并带有以下故事:

[...] “那将是 1.95 美元。”在这一点上,很自然地,我脱掉了我的裤子,那个家伙开始对我大喊警察和不雅曝光。我很困惑,说:“看,我只是想付钱给你——我会把我的裤子递给你,你在我的口袋里翻找,直到找到我的钱包,你会拿出来翻找现金.

“size getter”方法涉及一种更自然的方式,即自己从裤子里取出钱包并付款 :-)

它也直接来自OOP - Encapsulation 中最基本的概念之一。简而言之,它的目的是向外界隐藏(封装)类实现的尽可能多的细节。更少的耦合为您在未来提供更多的灵活性。如果这听起来太抽象或模糊,请不要担心。每个程序员(即我遇到的几乎每个程序员,包括我在内)最终都会到达一个点,即每个所谓的简单更改都必须在远处的代码部分进行大量修复。将耦合的报复击倒在你的手指下会让你回忆起这条规则,并永远记住它;)

最后,通常您不会创建代表包装的 vector 或类似内容的类。 vector 只是一个技术问题。通常这样的类代表一些特定元素的集合,这些元素在你的 Domain 逻辑级别上具有名称。所以大多数时候不是.getTheSizeOfMyInnerVector,而是.getRecordCount.getNumberOfStudents等。这类类的客户甚至不需要知道里面有一个std::vector。没关系,只要该类处理其维护某物集合的任务。例如,在这种情况下,上述灵活性可能意味着您可以切换到不同的容器,而不必担心类的客户端。并且无需翻遍可能在您的代码中使用此类的数千个地方。

【讨论】:

和我想说的差不多,只是说得更好:-) +1 但是我的类不只包含一个向量,geVectSize() 只是在“最小代码”中。我只是询问最佳实践。您的回答似乎是回答问题,但有点激进。 我没有发现该语言有任何不当之处。 关于裤子:“清洁工要裤子,卖家要钱,所以给卖家钱,给清洁工裤子!”就是这样,对吧? @sop 这样的事情。但关键是,不要向别人透露技术细节,这样他们就不会依赖他们,所以这些细节很容易改变。在这种情况下——卖家不需要知道你的裤子里有钱包,甚至不需要知道你穿着裤子。好吧,在这个细节点上,这个类比有点恶化;)我在 flexibility 部分添加了一些更具体的信息。【参考方案2】:

创建一个“大小获取器”并返回m_myVec.size() 的值,除非您确实需要完全访问该向量。 size getter 将更少的代码暴露给外界。如果您只是要提供一种获取向量的方法,那么它根本就不是私有的。

【讨论】:

+1。良好的封装意味着不仅隐藏向量,甚至隐藏存在 向量的事实(也就是实现细节)。【参考方案3】:

首先,正如评论者所指出的,如果您对向量使用 getter,则使其返回 const 引用而不是副本。

回答您的问题:这取决于您想要的数据封装级别。如果向量本身是类的实现细节,并且您不希望类的用户能够更改其内容(或仅通过类合同中明确定义的操作),则您不应该为(a参考)向量。

【讨论】:

以上是关于如何获取 C++ 类成员向量的大小?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 固定数量的向量大小作为类成员

C++ - 从向量中获取派生类变量

运行时在构造函数中初始化向量类成员——C++

C++中向量的大小

如何从 if 语句中获取类模板的实例? (C++)

C++ - 在 FOR 循环中从向量获取大小