如何通过构造函数将不带构造函数的“ Randomer”类的引用传递给类随机课程如何运作?

问题描述

我正在尝试将在“ 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,它就会一直存在。