我如何为使用 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 通常不是做事的最佳方式。设置整个集合不是很有效,因为必须复制内容。如果您真的只是想追加一个元素,那么效率尤其低,因为您最终会复制整个内容,而这本来可以是一个更简单的操作。但是你应该提供哪些操作取决于你的类的语义,所以我不能给你任何一般性的建议。
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
。Setter:C++03(没有移动语义)和 C++11(有移动语义)是有区别的。
C++03:由于C++03只有复制语义,复制vector的开销很大,你应该通过const引用再次传递参数。
void settest(const vector<number> &x){ test=x; } void settest2(const list<numb> &y){ test2=y; }
到目前为止这里没有变化。
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 自动从临时变量中移出,但函数参数不是临时变量,因此您必须从中移出。这样,如果可以移动源,则没有拷贝,只有两个移动,如果不能,则只有一个拷贝到参数,所有这些都带有一个重载。
通用:所有集合都有一个成员模板
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::begin
和std::end
允许其他类进入范围的函数(特别是接受也是普通的旧数组),所以你应该写:template <typename CollectionT> void settest(CollectionT const &x) { test.assign(std::begin(x), std::end(x)); }
如果您没有 C++11,但有 Boost ,您可能想使用来自 Boost.Range 的
boost::begin
和boost::end
相反。请注意,尽管这不允许移动语义,因为您只能从同一类型移动,并且假定类型可能不同。同时提供相同类型的移动重载和通用重载没有坏处。
Mutators:查看 list 和 vector have 的变异方法(实际上,它们具有相同的集合;唯一的区别是 vector 可以直接索引)并思考哪些方法对您的类提供有意义。如果将元素简单地附加到列表中是有意义的,那么提供对
push_back
和insert
(可能具有固定位置)成员的访问比通过简单的访问更有效二传手。例如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/