我已经看到了这个问题:Class design with vector as a private/public member?,但我觉得它没有回答这个问题。
我有一个名为PrimeSieve
的类,可以初始化为PrimeSieve s(10000)
来执行操作,例如检查10000以下的数字是否为素数或列出10000以下的所有素数。特别是,我是想知道如何执行后一种功能。
目前,我这样做,我认为这违反了OOP的原则:
class PrimeSieve {
public:
...
std::vector<long long> primes;
客户端永远不需要更改向量,但是我怎样才能让客户端迭代一些数字下的所有素数的向量(使用像vector.size()
这样的东西?我想过一个按值返回向量的访问器方法,但这似乎效率低下。
答案 0 :(得分:9)
我将该类定义为:
class PrimeSieve
{
public:
typedef std::vector<long long>::const_iterator const_iterator;
const_iterator begin() const { return primes.begin(); }
const_iterator end() const { return primes.end(); }
long long operator[](int index) const { return primes[i]; }
size_t size() const { return primes.size(); }
//rest of the members which compute the primes!
private:
std::vector<long long> primes ;
} ;
我认为该类的用户应该具有对该向量的只读访问权限,因此我在typedef定义中使用了const_iterator
。另请注意,operator[]
是const
成员函数,这意味着您只能访问该值,但无法对其进行修改。
用法:
PrimeSieve sieve(1000); //compute
//print to stdout
std::copy(sieve.begin(),
sieve.end(),
std::ostream_iterator<long long>(std::cout, " "));
答案 1 :(得分:6)
这是一种方法:
class PrimeSieve {
public:
const std::vector<long long>& getPrimes() const {
return primes ;
}
private:
std::vector<long long> primes ;
} ;
这里没有低效率 - 返回引用至少与返回指针一样有效。并且客户端可以迭代getPrimes
返回的向量(自然地使用const_iterator
。)
答案 2 :(得分:1)
public:
const std::vector<long long>* getPrimes() const { return ℙ }
private:
std::vector<long long> primes;
这使客户端可以访问指向const
的{{1}}指针,这意味着他们可以迭代它但不能修改它。
(我的语法可能有问题;自从我完成任何严肃的C ++以来已经过了几年)
答案 3 :(得分:1)
基本规则是:
您创建数据成员private
&amp;然后提供public
/ protected
成员函数来公开private
数据成员上提供的功能/操作。
您应该遵循相同的规则。
答案 4 :(得分:1)
另一种可能性是设计一个特殊的迭代器类:
class PrimeSieve {
mutable std::vector<long long> primes;
public:
class const_iterator;
friend class const_iterator;
class const_iterator{ // should probably inherit from some std::iterator class, not sure there
const PrimeSieve *domain;
unsigned index;
public:
const_iterator(const PrimeSieve &d): domain(&d), index(0) {}
const long long &operator *() const{return domain->primes[index];}
const_iterator &operator++(){
if (++index >= domain->primes.size()) {
// calculate a number of "new" primes here
}
return *this;
}
}
const_iterator begin() const {return const_iterator(*this);}
};
关于这一点的好处是容器现在是“无限的”:根据需要懒惰地计算素数,而不是达到给定的上限。