Объявление оператора < < () неверно. Для двоичной версии op < < вам не нужно объявлять второй параметр - предполагается, что он будет this
, если op < < является функцией-членом класса:
virtual ostream& operator<<(ostream& stream) = 0;
Более того, как упоминалось другими, операторы вставки потока должны быть глобальными функциями. Создание функций-членов просто не сработает.
Также не то, что не связано с вашим вопросом, но проблема, тем не менее. В исходной реализации вы передали абстрактный объект базового класса по значению, а не по ссылке или по указателю. Когда вы делаете это, вы «режете объект». Я уверен, что вы намеревались передать функции указатель базового класса на полиморфный тип, а затем полиморфно вызывать методы вызова функции. Например, вы пытались сделать что-то похожее на это:
#include
#include
#include
using namespace std;
class Base
{
public:
virtual void dump()
{
cout << "Base";
};
};
class Der : public Base
{
public:
void dump()
{
cout << "Der";
};
};
void DumpIt(Base b)
{
b.dump();
}
int main()
{
Der obj;
DumpIt(obj);
return 0;
}
... и ожидали, что на выходе будет «Der», но на самом деле на выходе получается «Base» из-за Object Slicing . Поскольку функция DumpIt () принимает базовый объект по значению, новый временный базовый объект создается на основе оригинала. Чтобы получить ожидаемую функциональность, вам нужно передать по ссылке или по указателю:
void DumpIt(Base & b)
{
b.dump();
}
Вывод этой функции - «Der».
Если вы не используете Не обращайте внимания на дерьмовую случайность, классический метод -
x[n+1] = (x[n] * x[n] + C) mod N
, где C и N - константы, C! = 0 и C! = -2, а N - простое число. Это типичный псевдослучайный генератор для факторинга Полларда Ро. Попробуйте C = 1 и N = 8051, они работают нормально.
Хотите верьте, хотите нет, но я использовал newx = oldx * 5 + 1 (или небольшую его вариацию) в нескольких видеоиграх. Случайность ужасна - это скорее скремблированная последовательность, чем случайный генератор. Но иногда это все, что вам нужно. Если я правильно помню, он перебирает все числа перед повторением.
У него ужасные характеристики. Он никогда не дает вам одно и то же число дважды подряд. Некоторые из нас провели кучу тестов на его вариациях, и мы использовали некоторые вариации в других играх.
Мы использовали его, когда нам не было подходящего модуля. Это просто сдвиг на два и два сложения (или умножение на 5 и одно сложение). Я бы никогда не использовал его сейчас для случайных чисел - я бы использовал LCG - но, возможно, он будет работать нормально для шейдера, где скорость имеет решающее значение, а ваш набор инструкций может быть ограничен.
Используйте линейный конгруэнтный генератор :
X_(n+1) = (a * X_n + c) mod m
Они не так сильны, но, по крайней мере, они хорошо известны и могут иметь длительные периоды. На странице Википедии также есть хорошие рекомендации:
Период общей LCG не превышает м, а для некоторых вариантов гораздо меньше чем это. LCG будет иметь полную период тогда и только тогда, когда:
1. c и m взаимно просты, 2. a - 1 делится на все простые делители m, 3. a - 1 делится на 4, если m делится на 4
В вершинных шейдерах иногда есть встроенные генераторы шума, которые можно использовать, например, функция cg noise ()
.