如何通过构造函数将不带构造函数的 class "Randomer" 的引用传递给 class。 class Randomer 是如何工作的?

How to pass the reference of the class "Randomer" without constructor to a class via constructor. How does the class Randomer work?

我正在尝试将在“main”中启动的 class“Randomer”的引用存储到另一个 class。
什么是最好的方法,指针或参考?

class“Randomer”如何取初始值。

这是如何工作的? operator()()

size_t operator()() {
        return dist_(gen_);
    }

随机取自: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' 的非 const 左值引用无法绑定到临时初始化列表

默认构造函数需要“Randomer” 否则错误:
Constructor for 'someClass' must explicitly initialize the reference member 'random'.

我想要两个构造函数。

最好的赌注是通过参考获得。

someClass 的两个构造函数都太晚初始化了 random 成员。在构造函数体被调用时,所有成员要么从成员初始化器列表中初始化,要么 default-initialized。 Randomer 没有默认的初始值设定项,所以这就是编译器所抱怨的。

要解决该问题,请编写成员初始化列表:

someClass(Randomer& random) : random(random) {}

默认构造函数有一个额外的问题:它需要构造一个 Randomer& 但在 someClass 被销毁时无法释放返回的对象。您可以切换到 std::shared_ptr<Randomer> 然后让自然引用计数来处理它,或者如果符合您的要求,您可以引用所有 someClass 对象共享的静态 Randomer

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 存在,它就会一直存在。