gpt4 book ai didi

c++ - 使用静态 const 成员构建类层次结构

转载 作者:行者123 更新时间:2023-11-30 04:24:07 25 4
gpt4 key购买 nike

我正在尝试为同余随机数生成器类创建一个合理的类层次结构(这意味着它有 3 个整数参数 - Mab).我决定基类应该为派生类提供一个接口(interface)(所以它应该是抽象的),M, a, b 应该是static const 在派生类中(因为它们在整个派生类中是相同的)。

由于 generate() 函数对于所有同余随机数生成器都是相同的,因此它的定义应该放在基类中。问题是这个函数使用了所有的M, a, b,但是这些不能被做成static const 在基类中。

为了说明问题,提供了一种可能的解决方案。然而,我对此并不完全满意,因为它为派生类的每个实例创建了 3 个额外的 long long 变量,所以我想知道是否可以提出更优雅的设计。

class RandomGenerator{
protected:
unsigned int seed;

const long long int M;
const long long int a;
const long long int b;

public:
RandomGenerator(unsigned int, long long, long long, long long);

virtual long double generate() const = 0;
};

long double RandomGenerator::generate() const{
static long long prv = seed;

return (long double) (prv = (a * prv + b) % M) / (M-1);
}

class RandU : public RandomGenerator {
private:
static const long long M = 2147483648LL;
static const long long a = 65539;
static const long long b = 0;

public:
RandU(unsigned int);

virtual long double generate() const;
};


RandU::RandU(unsigned int nseed): RandomGenerator(nseed, M, a, b){}

long double RandU::generate() const{
return RandomGenerator::generate();
}

最佳答案

解决这个问题的一种方法是在层次结构中添加一个类:

class RandomGenerator {
protected:
unsigned int seed;

public:
RandomGenerator(unsigned int, long long, long long, long long);

virtual long long getM() = 0;
virtual long long geta() = 0;
virtual long long getb() = 0;

virtual long double generate() const;
};


inline long double RandomGenerator::generate() const {
static long long prv = seed;
return (long double) (prv = (a * prv + b) % M) / (M-1);
}

class GeneralRandomGenerator : public RandomGenerator
{
const long long int M;
const long long int a;
const long long int b;
public:
virtual long long getM() { return M; }
virtual long long geta() { return a; }
virtual long long getb() { return b; }
};


class RandU : public RandomGenerator {
private:
static const long long M = 2147483648LL;
static const long long a = 65539;
static const long long b = 0;

public:
RandU(unsigned int);

virtual long long getM() { return RandU::M; }
virtual long long geta() { return RandU::a; }
virtual long long getb() { return RandU::b; }

virtual long double generate() const;
};


RandU::RandU(unsigned int nseed): RandomGenerator(nseed, M, a, b){}

inline long double RandU::generate() const {
return RandomGenerator::generate();
}

如您所见,我从 RandomGenerator 派生了 GeneralRandomGenerator。前者现在包含 Mab 的成员,而后者提供纯虚拟访问函数 getM()geta()getb()。在 GeneralRandomGenerator 中,实现了这些访问函数以返回成员。

但是在仍然派生自最高层的RandU中,访问器被定义为返回静态成员的值。

这样,最高级别的 generate() 函数可以通过访问器函数访问它需要的内容,而值实际上来自静态或非静态成员,或者可能来自某个地方完全不同。明显的优势是 RandU 不会为 Mab 占用任何空间,因为这些成员不'存在于其中。

然而,缺点是,即使在 GeneralRandomGenerator 中,对 M 等的访问也是通过调用虚函数来执行的,这意味着性能比通过编码直接访问静态成员可以实现什么。

避免这种情况的一种方法是提供 generate() 的通用 for 作为类外部的单独函数并传递 M, ab 作为参数:

namespace general
{
inline long double generate(long long a, long long b, long long M) const {
static long double prv = seed;
return (prv = (a * prv + b) % M) / (M-1);
}
}

class GeneralRandomGenerator
{
protected:
unsigned int seed;

public:
long long a;
long long b;
long long M;

virtual long double generate() const {
return general::generate(a,b,M);
}
};

class RandomU
{
private:
static long long a;
static long long b;
static long long M;
public:
virtual long double generate() const {
return general::generate(a,b,M);
}
};

关于c++ - 使用静态 const 成员构建类层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12996267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com