Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Значительно скорость выполнения драйвера можно увеличить с помощью использования шаблона С++. Шаблон С++ позволяет обращаться на прямую к памяти, тем самым заменить указатели, разыменование которых занимает время.
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
using namespace std;
class X
{
public:
X(const char *const name)
{
strncpy(this->name, name, sizeof(this->name));
}
void printName() const
{
cout << "My name is " << name << endl;
}
private:
char name[10];
};
void printHex(const void *const memory, const size_t memorySize)
{
const ios_base::fmtflags savedFmtflags = cout.flags();
for (size_t i = 0; i < memorySize; ++i)
{
const unsigned int byteValue = reinterpret_cast<const uint8_t *const>(memory)[i];
cout << hex << setw(2) << setfill('0') << byteValue << ' ';
}
cout << endl;
cout.flags(savedFmtflags);
}
int main()
{
static uint8_t xMemoryPoolBytes[sizeof(X)];
static X *const xMemoryPool = reinterpret_cast<X*>(xMemoryPoolBytes);
printHex(xMemoryPoolBytes, sizeof(xMemoryPoolBytes));
// Понадобился объект класса X
const X *const instance = new (xMemoryPool) X("Ivan");
instance->printName();
// Больше не нужен
instance->~X();
operator delete (xMemoryPool);
printHex(xMemoryPoolBytes, sizeof(xMemoryPoolBytes));
return EXIT_SUCCESS;
}00 00 00 00 00 00 00 00 00 00
My name is Ivan
49 76 61 6e 00 00 00 00 00 00int main()
{
static uint8_t xMemoryPoolBytes[sizeof(X)]; /**< Это и есть статический стек для объектов? Здесь он объевлен ровно на один объект, а как быть, есть я хочу много объектов? С объявлением пула на несколько понятно, а как создавать нескоолько объектов в этом пуле? */
static X *const xMemoryPool = reinterpret_cast<X*>(xMemoryPoolBytes); /**< Тут Вы приводите область памяти к типу Х? reinterpret_cast это стандартная функция? */
printHex(xMemoryPoolBytes, sizeof(xMemoryPoolBytes)); /**< Это я так понимаю Вы сделали для наглядности того, что происходит в стеке */
/** далее все ясно */
const X *const instance = new (xMemoryPool) X("Ivan");
instance->printName();
instance->~X();
operator delete (xMemoryPool);
printHex(xMemoryPoolBytes, sizeof(xMemoryPoolBytes));
return EXIT_SUCCESS;
}
Это и есть статический стек для объектов? Здесь он объевлен ровно на один объект, а как быть, есть я хочу много объектов? С объявлением пула на несколько понятно, а как создавать нескоолько объектов в этом пуле?Вы всё правильно поняли. Если хотите создавать несколько объектов, вам нужно указывать соответствующие адреса памяти в пуле, то бишь делать смещение на i*sizeof(X) байт, где i — номер объекта.
Тут Вы приводите область памяти к типу Х? reinterpret_cast это стандартная функция?Типа того. В C++, помимо стандартного сишного приведения типов (X*) xMemoryPoolBytes, есть ещё:
X *instance1 = new (xMemoryPool[0]) X("Ivan");
X *instance2 = new (xMemoryPool[1]) X("Nikolai");
...
А без приведения к X* пришлось бы писать уродливое new (xMemoryPoolBytes + sizeof(X)).Это я так понимаю Вы сделали для наглядности того, что происходит в стекеИменно — чтобы было видно, как поменялись байты в статическом пуле после того, как вы создали в нём объект и использовали его. Отчётливо видно, что «Ivan» записалось в пул.
operator delete (xMemoryPool);не нужно, написал на автомате. Не нужно динамически удалять память пула, мы же её выделили статически :D хлопнул себя по лбу. Нужно только вручную вызвать деструктор, раз мы не освобождаем память.Вы всё правильно поняли. Если хотите создавать несколько объектов, вам нужно указывать соответствующие адреса памяти в пуле, то бишь делать смещение на i*sizeof(X) байт, где i — номер объекта.
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iomanip>
#include <iostream>
using namespace std;
void printHex(const void *const memory, const size_t memorySize)
{
const ios_base::fmtflags savedFmtflags = cout.flags();
for (size_t i = 0; i < memorySize; ++i)
{
const unsigned int byteValue = reinterpret_cast<const uint8_t *const>(memory)[i];
cout << hex << setw(2) << setfill('0') << byteValue << ' ';
}
cout << endl;
cout.flags(savedFmtflags);
}
class X
{
public:
X(const uint8_t n)
{
snprintf(name, sizeof(name), "Ivan%d", n);
}
void printName() const
{
cout << "My name is " << name << endl;
}
private:
char name[10];
};
struct XBlock
{
public:
X *create(const uint8_t n)
{
return new (memory) X(n);
}
static void destroy(X *const instance)
{
instance->~X();
}
private:
uint8_t memory[sizeof(X)];
};
enum { MAX_X_INSTANCES = 4 };
static XBlock xPool[MAX_X_INSTANCES];
int main()
{
printHex(xPool, sizeof(xPool));
X *xInstances[MAX_X_INSTANCES];
for (size_t i = 0; i < MAX_X_INSTANCES; ++i)
{
xInstances[i] = xPool[i].create(i);
xInstances[i]->printName();
}
// ...
for (size_t i = 0; i < MAX_X_INSTANCES; ++i)
XBlock::destroy(xInstances[i]);
printHex(xPool, sizeof(xPool));
return EXIT_SUCCESS;
}
Драйвера на С++ для STM8L051F3