【问题标题】:Best way to mutate a private vector in a class在类中改变私有向量的最佳方法
【发布时间】:2014-05-11 21:22:07
【问题描述】:

我有一个关于更好的编程实践的问题。说,我有以下课程:

class MyClass {
public: 
    vector<double> data() { return data_; }
    void set_data(int index, double value) { data_[index] = value; }
private:
    vector<double> data_;
};

我有私有向量 data_ 和访问器/修改器函数。在公共data_ 的情况下使用operator= 非常方便。但是,我需要将 data_ 设为私有并通过成员函数访问/改变它。但我不确定构造 mutator 函数的最佳方法。到目前为止,我最好的方法是示例中的方法。有什么建议吗?

【问题讨论】:

  • 我不明白为什么示例中的那个不好...一个小的改进是使结构中的 mutator 只是一个原型,并在程序中具有较低的功能.
  • 更多上下文会有所帮助。仅考虑到这一点,最好的方法是说using MyClass = std::vector&lt;double&gt;;
  • 您的课程,正如所写的那样,与独立的std::vector&lt;double&gt; 一样好,并且没有告诉我们您想要实现的目标。这使得很难就“更好的方法”给出建议。
  • 不要仅仅为了上课而上课。每个班级都应该有一个单一的、不同的目的和责任。如果您的班级有太多职责,请将其拆分。如果没有,请将其删除。
  • 就目前而言,您的data() 方法应该是const,并且您无法设置向量的大小。你想如何创建这个类?

标签: c++ class private mutators


【解决方案1】:

这取决于你想对课程做什么,但我建议:

double getAt(size_t index) const { return data_.at(index); }
void setAt(size_t index, double value) { data_.at(index) = value; }

这样做的好处是您可以更改类的内部实现,例如使用不同的 STL 容器,并且您不需要更改接口。请注意,getter 是const

如果性能至关重要并且您信任调用者,那么您可以省略边界检查:

double getAt(size_t index) const { return data_[index]; }
void setAt(size_t index, double value) { data_[index] = value; }

但是能够设置整个向量并且您不介意公开实现可能很有用,在这种情况下您可能需要类似的东西:

void setData(std::vector<double> data) { data_ = std::move(data); }

请注意,setData 按值获取向量并将其移动到私有成员变量中,这意味着如果调用者传递一个右值,则不会进行复制。

如果您需要获取整个向量,您可以选择。如果向量不是太大,性能并不重要,或者无论如何您都需要制作副本,那么按值返回就可以了,这将是我的首选:

std::vector<double> getData() const { return data_; }

否则通过引用返回:

const std::vector<double>& getData() const { return data_; }
std::vector<double>& getData() { return data_ } 

但请注意,这完全破坏了封装,尤其是非常量版本。

【讨论】:

    【解决方案2】:

    提供数据访问权限的最简单方法。

    double& at(size_t index) { return data_[index]; }
    double const& at(size_t index) const { return data_[index]; }
    

    【讨论】:

    • 这在我看来有点像“返回对象内部的句柄”。
    • @ChrisDrew 这几乎是真的。唯一的区别是您可以将数据的内部持有者更改为double 的数组,并且仍然能够支持该接口。如果您发疯了,您甚至可以将内部数据更改为std::map,并且仍然能够支持该接口。1
    • @R Sahu:没错,但封装的内容远不止这些。我们还想保护私人数据。 Scott Meyers 说第二种方法的问题在于它可能导致“悬空手柄”,请参阅ideone.com/McIGCp。 Scott 确实继续承认 vector 上的 operator[] 返回对容器中数据的引用,但“......这样的函数是例外,而不是规则”。
    • @ChrisDrew 所有 STL 容器都返回对它们持有的数据的引用。很明显,这些都是意见问题。悬空指针的风险是 C/C++ 编程的一部分。您必须了解潜在的陷阱,并使用您的类接口来应对随之而来的风险。按值返回对象适用于基本类型而不是太大的 POD。当您有容器和复杂的聚合对象时,它们就会分解。
    • @R Sahu:但您并没有承担编写通用 STL 容器的任务。在这种情况下,您只返回 double 那么为什么不按值返回呢?它将同样快速且不易出错。
    猜你喜欢
    • 2012-09-15
    • 2012-11-12
    • 2020-05-25
    • 2011-08-02
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    相关资源
    最近更新 更多