- Polimorfismo em C++
O polimorfismo permite que um mesmo contrato de interface se comporte de formas distintas conforme o tipo concreto do objeto. Em C++, ele se manifesta de duas maneiras principais:
1.1 Polimorfismo em Tempo de Compilação
Resolvido durante a compilação, geralmente por meio de sobrecarga de funções e operadores.
class Calculadora {
public:
int soma(int x, int y) { return x + y; }
double soma(double x, double y) { return x + y; }
};
1.2 Polimorfismo em Tempo de Execução
Implementado com funções virtuais e ponteiros/referências para a classe base.
class Forma {
public:
virtual void desenhar() const {
std::cout << "Desenhando forma genérica" << std::endl;
}
virtual ~Forma() = default;
};
class Circulo : public Forma {
public:
void desenhar() const override {
std::cout << "Desenhando círculo" << std::endl;
}
};
void renderizar(const Forma& figura) {
figura.desenhar();
}
Vantagens: reutilização de código, extensibilidade, vinculação dinâmica e maior clareza em sistemas com famílias de objetos.
- Busca de Texto no Vim
Para localizar palavras dentro do editor Vim:
- Busca para frente:
/termoe pressioneEnter. - Busca para trás:
?termoe pressioneEnter. - Próxima ocorrência:
n. - Ocorrência anterior:
N.
- Diferença entre
structeunion
| Aspecto | struct | union |
|---|---|---|
| Memória | Soma dos membros + alinhamento | Tamanho do maior membro |
| Armazenamento | Todos os membros simultaneamente | Apenas um membro por vez |
| Inicialização | Lista completa de valores | Apenas o primeiro membro |
struct Pessoa {
char nome[20];
int idade;
};
union Valor {
int inteiro;
float decimal;
char caractere;
};
struct Pessoa p = {"Ana", 25};
union Valor v = {100}; // inicializa o membro int
- Enumerações em C
O tipo enum define constantes inteiras nomeadas, melhorando a legibilidade e a manutenção.
typedef enum {
DESLIGADO = 0,
LIGADO,
STANDBY
} Estado;
Estado motor = LIGADO;
Quando combinado com typedef, simplifica a declaração de variáveis e restringe o escopo quando usado em C99 ou superior.
- Fluxo de Uso de Interrupções no STM32
Configuração típica de uma interrupção externa (EXTI) usando a Standard Peripheral Library:
void inicializar_gpio(void) {
GPIO_InitTypeDef cfg;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
cfg.GPIO_Pin = GPIO_Pin_0;
cfg.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &cfg);
}
void inicializar_nvic(void) {
NVIC_InitTypeDef nvic;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
nvic.NVIC_IRQChannel = EXTI0_IRQn;
nvic.NVIC_IRQChannelPreemptionPriority = 1;
nvic.NVIC_IRQChannelSubPriority = 0;
nvic.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic);
}
void inicializar_exti(void) {
EXTI_InitTypeDef exti;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_ClearITPendingBit(EXTI_Line0);
exti.EXTI_Line = EXTI_Line0;
exti.EXTI_Mode = EXTI_Mode_Interrupt;
exti.EXTI_Trigger = EXTI_Trigger_Falling;
exti.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti);
}
void EXTI0_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
EXTI_ClearITPendingBit(EXTI_Line0);
GPIOA->ODR ^= GPIO_Pin_5;
}
}
- Sinais Comuns no Linux
Alguns sinais importantes para aplicações embarcadas e controle de processos:
SIGINT(2): interrompe um processo via Ctrl+C.SIGKILL(9): encerramento forçado, não pode ser capturado.SIGTERM(15): solicita encerramento ordenado.SIGSEGV(11): violação de acesso à memória.SIGALRM(14): alarme de temporização.
- Funções Comuns da
string.h
| Função | Descrição |
|---|---|
strlen |
Retorna o comprimento de uma string, sem contar o '\0'. |
strcpy |
Copia uma string para outra. |
strncpy |
Copia até n caracteres, preenchendo com nulos se necessário. |
strcat |
Concatena duas strings. |
strncat |
Concatena até n caracteres. |
strcmp |
Compara duas strings lexicograficamente. |
strncmp |
Compara até n caracteres. |
- Detecção de Endianness
Endiannesss define a ordem de armazenamento dos bytes de um valor multi-byte na memória. O código a seguir identifica se a arquitetura é little-endian ou big-endian:
#include <stdio.h>
int main(void) {
unsigned int valor = 1;
unsigned char *ptr = (unsigned char *)&valor;
if (ptr[0] == 1) {
printf("Little-endian\n");
} else {
printf("Big-endian\n");
}
return 0;
}
- Ponteiros Inteligentes em C++
Introduzidos para gerenciar automaticamente a vida útil da memória dinâmica, reduzindo vazamentos:
std::unique_ptr<T>: ownership exclusivo.std::shared_ptr<T>: ownership compartilhado com contagem de referências.std::weak_ptr<T>: observa um recurso sem aumentar sua contagem de referências.
- Benefícios do Alinhamento de Memória em Estruturas
O alinhamento otimiza o acesso do processador a variáveis, respeitando limites de endereço. Ele evita leituras múltiplas e exceções de hardware, mesmo que aumente ligeiramente o consumo de memória por causa do preenchimento.
struct Exemplo {
char a;
int b;
char c;
};
Em uma arquitetura de 32 bits, a estrutura acima pode ocupar 12 bytes devido ao preenchimento, em vez de 6.
std::vectorvs Arrays em C++
| Característica | Array | std::vector |
|---|---|---|
| Tamanho | Fixo em tempo de compilação | Dinâmico em tempo de execução |
| Memória | Pode estar na stack ou heap | Sempre na heap, gerenciada automaticamente |
| Funcionalidades | Acesso por índice | push_back, size, empty, erase, etc. |
| Segurança | Menor | Maior, com iteradores e RAII |
- Formas do Operador
newem C++
// Alocação simples
int *p1 = new int;
// Alocação com inicialização
int *p2 = new int(42);
// Alocação de array
int *p3 = new int[10];
// Alocação com construtor default explícito
std::string *p4 = new std::string();
// Sobrecarga customizada
void* operator new(size_t size) {
return std::malloc(size);
}
- Funções
inlineem C++
Uma função marcada com inline sugere ao compilador que substitua o corpo da função diretamente no ponto de chamada, eliminando o overhead da chamada. É indicada para funções pequenas e frequentemente executadas, mas a decisão final de expansão permanece com o compilador.
inline int quadrado(int x) {
return x * x;
}