c ++中向量和列表的setter和getter

1 c++ getter setter list vector

我怎么能用setter和getter来表示用vector和list声明的变量.

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;

 }
Run Code Online (Sandbox Code Playgroud)

我试图定义矢量和列表的set和get方法,如上所述是正确的吗?请更正它.以及如何从main调用set和get函数.

Jan*_*dec 11

收集的getters不是问题,但是setter通常不是最好的做事方式.由于必须复制内容,因此设置整个集合效率不高.如果你真的只想附加一个元素,那么效率特别低,因为你最终会复制整个内容只是为了简单的操作.但是你应该提供哪些操作取决于你班级的语义,所以我不能给你任何一般的建议.

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

    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
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,我还标记了方法const.这允许同时调用它们,const abc &因此您可以abc通过其他接口的const引用返回.

  2. Setter:C++ 03(没有移动语义)和C++ 11(移动语义)之间存在差异.

    1. C++ 03:由于C++ 03只有复制语义而且复制向量很昂贵,所以你应该通过const引用再次传递参数.

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

      到目前为止没有变化.

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

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

      C++ 11会自动从临时代码移动,但函数参数不是临时的,因此您必须从中移动.这样,如果可以移动源,则没有副本,只有两个移动,如果不能,则只有一个副本到参数,所有都有一个重载.

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

      template <typename IteratorT>
      void settest(IteratorT begin, IteratorT end) {
          test.assign(begin, end);
      }
      
      Run Code Online (Sandbox Code Playgroud)

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

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

      在C++ 11中,有非成员函数std::beginstd::end函数允许将其他类放入范围(特别是接受普通旧数组),因此您应该编写:

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

      如果你没有C++ 11,但有Boost,你可能想要使用boost::beginboost::end来自Boost.Range.

      请注意,这不允许移动语义,因为您只能从相同的类型移动,并且这假设类型可能不同.提供相同类型的移动过载和通用过载都没有坏处.

  3. 变异器:看看变异方法列表和向量有(实际上两者都有相同的集合;唯一的区别是向量可以直接索引)并考虑哪些对你的类提供有意义.如果简单地将元素附加到列表中是有意义的,那么提供对push_backinsert(可能具有固定位置)成员的访问比通过普通的setter更有效.例如

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

    和其他方法类似.