C++: mity i fakty

W latach 90. rozpowszechniła się w kręgach zainteresowanych tematyką opinia, że język C++ nie nadaje się do tego, żeby pisać w nim programy dla mikrokontrolerów jednoukładowych. W przypadku małych systemów 8- i 16-bitowych, dominujących w tamtym okresie, jest to zapewne prawda. Ale dziś, w dobie tanich mikroprocesorów 32-bitowych o wielkiej (w porównaniu do tych z poprzednich dekad) mocy przetwarzania i znacznych zasobach, można sobie zadać pytanie, na ile ta niezbyt pochlebna dla C++ opinia ma nadal pokrycie w faktach, a na ile jest utrzymującym się siłą inercji mitem.

Posłuchaj
00:00
Spis treści

Szablony

Szablony przypominają nieco makrodefinicje, które kompilator rozwija w całe klasy. Ponieważ jedno wywołanie szablonu umieszczone w kodzie programu może zostać rozwinięte w klasę, beztroskie korzystanie z szablonów może się szybko zemścić, powodując gigantyczny rozrost gotowego programu. Dzieje się tak zwłaszcza przy zastosowaniu starszych kompilatorów, które każde odwołanie do szablonu rozwijają w oddzielną klasę; ale nowsze kompilatory i linkery starają się wykrywać duplikaty i tworzyć najwyżej po jednej, unikalnej kopii każdego szablonu.

Szablony, jeśli zastosujemy je z głową, mogą zaoszczędzić programiście wiele wysiłku przy niewielkich stratach rozmiarów programu (lub w ogóle bez takich strat). W końcu przeważnie dużo łatwiej jest skorzystać z gotowego szablonu dostarczanego przez bibliotekę niż pisać własną złożoną klasę od początku.

Przykład poniżej ilustruje użycie szablonu:

template<typename T> class A
{
private:
T value;
public:
A(T);
T f();
};
template<typename T> A<T>::A(T initial)
{
value = initial;
}
template<typename T> T A<T>::f()
{
return value;
}
int main()
{
A<int> a(1);
a.f();
return 0;
}

Jak powiedziano powyżej, szablony działają podobnie jak makrodefinicje, można więc zamiast nich spróbować użyć makr preprocesora w języku C:

#define A(T)
struct A _ ##T
{
T value;
};

void konstruktor _ A _ ##T(struct A _ ##T *this,
T initial)
{
(this)->value = initial;
}

T A _ f _ ##T(struct A _ ##T *this)
{
return (this)->value;
}
A(int) /* tu makro rozwija się w "klasę" A _
int */
int main()
{
struct A _ int a;
konstruktor _ A _ int(&a, 1);
A_ f _ int(&a);
return 0;
}

Jak widać, rzecz sama w sobie jest jak najbardziej wykonalna, ale widać też, że jest to niezbyt praktyczne rozwiązanie w przypadku bardziej skomplikowanego kodu.

Spis treści
Powiązane treści
PRQA wprowadza narzędzie do analizy statycznej QA·C++ w nowej wersji V3.2
Zobacz więcej w kategorii: Technika
Komponenty
Stopnie ochrony obudów – co kryje się pod kodem IP65?
Zasilanie
Jak kompensować moc bierną w małej firmie, by płacić mniej za energię bierną?
Projektowanie i badania
SigmaLabs - polska elektronika w kosmosie
Optoelektronika
Optical bonding vs. air bonding
Optoelektronika
IP69 w wyświetlaczach przemysłowych – co to oznacza i dlaczego jest ważne?
Komponenty
Radiatory – cisi bohaterowie technologii, czyli jak odprowadzać ciepło, zanim stanie się problemem
Zobacz więcej z tagiem: Artykuły
Targi krajowe
Targi Euro Target Show 2026
Magazyn
Marzec 2026
Magazyn
Luty 2026

Jak kompensować moc bierną w małej firmie, by płacić mniej za energię bierną?

Z reguły małej firmy nie stać na zakup automatycznego kompensatora mocy biernej. Niemniej, sytuacja nie jest bez wyjścia i w tym artykule na prostym przykładzie pokazane zostało podejście do rozwiązania problemu mocy biernej.
Zapytania ofertowe
Unikalny branżowy system komunikacji B2B Znajdź produkty i usługi, których potrzebujesz Katalog ponad 7000 firm i 60 tys. produktów