c++ - c++中 vector 和列表的setter和getter

标签 c++ list vector setter getter

我如何为使用 vector 和 list 声明的变量使用 setter 和 getter。

class abc{

    private:
       vector<number> test;
       list<numb> test2; 

    public:
       void settest(const vector<number> &x){
               test=x;

         }
       vector<number> gettest(){

         return test;
       }

       void settest2(const list<numb> &y){
               test2=y;

         }
       vector<numb> gettest2(){

         return test2;
       }


};
 int main(){
   abc object;

 }

我尝试像上面那样为 vector 和列表定义设置和获取方法是否正确?请更正。 以及如何从 main 中调用 set 和 get 函数??。

最佳答案

集合的getter 不是问题,但setter 通常不是做事的最佳方式。设置整个集合不是很有效,因为必须复制内容。如果您真的只是想追加一个元素,那么效率尤其低,因为您最终会复制整个内容,而这本来可以是一个更简单的操作。但是你应该提供哪些操作取决于你的类的语义,所以我不能给你任何一般性的建议。

  1. Getter:对于重要的数据结构,最合适的形式是 const 引用。这允许调用者查看 vector ,包括在其上运行任何非变异算法,同时避免复制任何内容:

    vector<number> const &gettest() const { return test; }
    //                              ^^^^^ even on const abc
    //             ^^^^^^^ read-only subinterface
    list<numb> const &gettest2() const { return test2; }
    //                           ^^^^^ even on const abc
    //         ^^^^^^^ read-only subinterface
    

    请注意,我还将方法标记为 const。这也允许在 const abc & 上调用它们,因此您可以通过来自其他接口(interface)的 const 引用返回 abc

  2. Setter:C++03(没有移动语义)和 C++11(有移动语义)是有区别的。

    1. C++03:由于C++03只有复制语义,复制vector的开销很大,你应该通过const引用再次传递参数。

       void settest(const vector<number> &x){ test=x; }
       void settest2(const list<numb> &y){ test2=y; }
      

      到目前为止这里没有变化。

    2. C++11:移动语义改变了一些东西。上面的代码不能在赋值中使用移动语义,因为它有常量左值引用,因此不能从它移动。您可以添加右值引用重载,但实际上更容易通过 value 传递:

      void settest(vector<number> x) { test=std::move(x); }
      //                       request move ^^^^^^^^^
      void settest2(list<numb> y) { test2=std::move(y); }
      //                     request move ^^^^^^^^^
      

      C++11 自动从临时变量中移出,但函数参数不是临时变量,因此您必须从中移出。这样,如果可以移动源,则没有拷贝,只有两个移动,如果不能,则只有一个拷贝到参数,所有这些都带有一个重载。

    3. 通用:所有集合都有一个成员模板assign,允许从两个迭代器设置它们。所以你可以编写一个模板 setter ,允许从任何类型的集合中设置它,并且只能从集合的一部分中设置它:

      template <typename IteratorT>
      void settest(IteratorT begin, IteratorT end) {
          test.assign(begin, end);
      }
      

      列表版本相同,只是设置了不同的成员。这是使用范围的 C++ 标准方法,但它要求调用者显式引用集合两次。为方便起见,可以添加以下内容 (C++03):

      template <typename CollectionT>
      void settest(CollectionT const &x) {
          test.assign(x.begin(), x.end());
      }
      

      在 C++11 中,有非成员函数 std::beginstd::end 允许其他类进入范围的函数(特别是接受也是普通的旧数组),所以你应该写:

      template <typename CollectionT>
      void settest(CollectionT const &x) {
          test.assign(std::begin(x), std::end(x));
      }
      

      如果您没有 C++11,但有 Boost ,您可能想使用来自 Boost.Rangeboost::beginboost::end相反。

      请注意,尽管这不允许移动语义,因为您只能从同一类型移动,并且假定类型可能不同。同时提供相同类型的移动重载和通用重载没有坏处。

  3. Mutators:查看 list 和 vector have 的变异方法(实际上,它们具有相同的集合;唯一的区别是 vector 可以直接索引)并思考哪些方法对您的类提供有意义。如果将元素简单地附加到列表中是有意义的,那么提供对 push_backinsert(可能具有固定位置)成员的访问比通过简单的访问更有效二传手。例如

    void appendtest(number x) {
        test.push_back(x);
    }
    
    template <typename IteratorT>
    void appendtest(IteratorT begin, IteratorT end) {
        test.insert(test.end, begin, end);
    }
    

    其他方法类似。

关于c++ - c++中 vector 和列表的setter和getter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21227060/

相关文章:

c++ - 将 vector 数组作为函数参数传递(值不会改变)

c++ - 如何从对象 vector 中删除元素?

c++ - 双向链表默认类型名节点

c# - 有人可以告诉我 List、Collection 和 Enumerable 之间有什么区别?

c++ - 类的二维 vector 在访问函数时出错

c++ - 一些 C++ vector 问题

c++ - 方法存在检查器代码在 vs2015 中中断

c++ - 合并多个 map

c++ - 无法再正确读取文本文件

r - 如何检查日期是否在 R 中的间隔列表内?