问题描述
我正在尝试将在“ main”中启动的“ Randomer”类的引用存储到另一个类。
最好的方法是指针还是引用?
“ Randomer”类如何获取初始值。
这是如何工作的?
operator()()
size_t operator()() {
return dist_(gen_);
}
Randomer摘自:https://www.mmbyte.com/
class Randomer {
// random seed by default
std::mt19937 gen_;
std::uniform_int_distribution<size_t> dist_;
public:
/* ... some convenient ctors ... */
Randomer(size_t min,size_t max,unsigned int seed = std::random_device{}())
: gen_{seed},dist_{min,max} {
}
// if you want predictable numbers
void SetSeed(unsigned int seed) {
gen_.seed(seed);
}
size_t operator()() {
return dist_(gen_);
}
};
someClass{
protected:
Randomer& random;
public:
someClass(){
this->random = ....; // <----------------------
this->random{0,9}; // this doesn't work.
}
someClass(Randomer& random){
this->random = random; // <----------------------
}
}
int main()
{
Randomer randomer{0,9}; // how does this work?
someClass* test = new someClass(randomer);
int randomNumber = randomer(); // // how does this work?
std::cout << "randomNumber" << randomNumber << endl;
return 0;
}
结果错误:
error: constructor for 'someClass' must explicitly initialize the member 'random' which does not have a default constructor.
编辑: 如果我尝试参考:
someClass{
protected:
Randomer& random;
public:
someClass(): : random(new Randomer{0,9}){ // this doesn't work either
}
someClass(): random{0}{ // <------ error 1
}
someClass(): random{0,9}{ // <------ alternative,error 2
}
someClass(Randomer& random): random(random){ // all good
this->random = random;
}
void somefunction(){
int randomNumber = this->random(); // no complaing
}
}
int main()
{
Randomer randomer{0,9}; // is created here
someClass* some = new someClass;
someClass* some2 = new someClass(randomer);
}
错误:
1:没有匹配的构造函数,用于初始化“ Randomer&”
2:对“ Randomer”类型的非常量左值引用不能临时绑定到初始化程序列表
默认构造函数需要“ Randomer”
否则出现错误:Constructor for 'someClass' must explicitly initialize the reference member 'random'.
我想同时拥有两个构造函数。
最佳选择是通过引用获得的。
解决方法
someClass
的两个构造函数都太晚初始化random
成员。到构造函数主体被调用时,所有成员要么从成员初始化器列表中初始化,要么被默认初始化。
Randomer
没有默认的初始化程序,因此编译器会抱怨这一点。
要解决该问题,请编写成员初始化器列表:
someClass(Randomer& random) : random(random) {}
默认构造函数还有一个额外的问题:它需要构造一个Randomer&
,但是在someClass
被销毁时无法释放返回的对象。您可以切换到std::shared_ptr<Randomer>
,然后让自然引用计数来处理它,或者可以满足所有Randomer
对象之间共享的静态someClass
的引用(如果满足您的要求):
class someClass {
// Note: inline static is a C++17 feature. You will need
// to split declaration and definition in older C++ versions.
static inline Randomer global_randomer{0,9};
public:
someClass() : randomer{global_randomer} {}
};
关于您的其他问题:
-
operator()()
只是函数调用操作符(完全拼写为:operator()
),并且您在定义它时没有任何参数,因此添加了一个空的参数列表。 - 括号初始化是C ++ 11中的新功能。
- 假设“源”仍在范围内,则通过引用传递Randomer很好。如果不是,那么您可能想使用
std::shared_ptr<Randomer>
,因此只要存在shared_ptr
,它就会一直存在。