Lab C++

Codificação Eficiente

Não basta conhecer a sintaxe, é preciso conhecer a linguagem, saber a melhor forma de fazer.

Tags: c++

Contando Ocorrências com std::set

A biblioteca STL foi incorporada no C++ em 1994, e veio padronizar um conjunto de estruturas de dados muito úteis. Neste post vamos abordar uma das mais simples: std::set.

std::set é um container para armazenamento único e ordenado. Faz uso de template para ser possível utilizar quaisquer tipos ou classes que possam ser comparadas, o container oferece, inclusive opções para definir métodos de comparação e de alocação.

(mais…)

Trocar Valor de Variáveis

Esse exercício é muito interessante, apesar de ser pouco usual, pessoalmente nunca vi um caso em que isso realmente necessário.

A proposta do exercício é trocar o valor de duas variáveis int, ou derivadas, sem utilizar uma terceira variável. Como a maioria dos exercícios mal elaborados existe a forma esperada e a forma inesperada, mas que entrega o mesmo resultado.

(mais…)

Evitando Hadouken de Ifs

Hadouken de Ifs nasceu de um meme, ilustrado abaixo. Basicamente é um conjunto de ifs aninhados, normalmente um conjunto de validações, que, por conta de inexperiência ou inabilidade do desenvolvedor, acaba por formar uma estrutura difícil de compreender e consequentemente mais difícil de ser mantida, implicando em maiores custos de manutenção do código.

(mais…)

Design Patterns: Factory Methods

O pattern Factory Methods é uma forma de encapsular o construtor de forma a tornar a criação de objetos muito mais flexível e acessível às classes derivadas. Basicamente é um método estático chamado no lugar no operador new para alocar uma nova instância da classe. Veja o exemplo a seguir:


#include <iostream>
#include <string>

class Part {
private:
protected:
	std::string id;

	Part() {
		id = "";
		std::cout << "  -> New empty part constructor" << std::endl;
	}
	Part(std::string id) {
		this->id = id;
		std::cout << "  -> New part constructor by id" << std::endl;
	}
	Part(std::string name, std::string instance, std::string rev) {
		std::cout << "      -> query for part on database" << std::endl;
		std::cout << "  -> New part construcutor by part data" << std::endl;
	}

public:
	~Part() {
		std::cout << "-> Part destructor" << std::endl;
	}

	static Part* createPart() {
		std::cout << "-> Execute checks and preparations for new empty part" << std::endl;
		return new Part();
	}
	static Part* createPart(std::string id) {
		std::cout << "-> Execute checks and preparations for new part by id" << std::endl;
		return new Part(id);
	}
	static Part* createPart(std::string name, std::string instance, std::string rev) {
		std::cout << "-> Execute checks and preparations for new part by part data" << std::endl;
		return new Part(name, instance, rev);
	}
};


int main() {
	Part* first = Part::createPart();
	Part* second = Part::createPart("0123456789ABCDEF");
	Part* third = Part::createPart("Name", "1", "1");

	delete first, second, third;
}

Neste exemplo o retorno para os objetos é em forma de ponteiros, mas é possível também ser feito por valor, ou referência, facilitando a gestão da memória.

Cuidados

Muito cuidado com a documentação de códigos deste tipo. É necessário deixar bem documentado a forma de desalocação dos objetos alocados, seja deixando a responsabilidade da desalocação (delete) pelo método que efetuou o chamado, ou por um método específico para isso (Part::destroyPart(), por exemplo).

Profissionalmente

Algumas equipes não aceitam a utilização do operador new, sendo obrigatório sempre haver um Factory Method, outras apenas incentivam quando há necessidade.

Quanto maior a complexidade de inicialização de um objeto, mais indicado é o Factory Method. Uma máquina de estados é um bom exemplo, ainda mais se os estados e suas conexões dependerem de uma fonte de dados externa, como um arquivo ou uma base de dados.

Design Patterns: Uma Nova Série de Artigos

A partir desta semana vamos começar uma série de artigos sobre Design Patterns, snippets tão úteis como controversos. Apesar das críticas contrárias a sua utilização, sua importância é inegável, não apenas como uma biblioteca de padrões mas principalmente como uma forma de estudar diferentes abordagens a soluções comuns no dia-a-dia do desenvolvimento.

(mais…)

Solução: Imprimir o Meio da String

Há alguns meses apareceu na lista cppbrasil uma dúvida, como retornar o(s) caracteres do meio de uma string. Por exemplo:

  • AMARELO -> R
  • VERMELHO -> ME
  • AZUL -> ZU
  • VERDE -> R
(mais…)

C++11: Métodos Modernos da std::string

No post de hoje vamos citar os novos métodos da std::string no C++11, alguns são muito bacanas e implementam funcionalidades populares em outras linguagens. Vamos avaliá-las conforme a versão em que estão disponível com exemplos.

(mais…)

Solução: Abertura e Fechamento de Parênteses

Hoje uma nova seção no Lab C++. As sextas-feiras serão reservadas para solução de exercícios e problemas encontrados em provas, cursos técnicos, superior, concursos, entrevistas de emprego, etc. Esta seção é voltada para tirar dúvidas dos leitores, portanto envie suas dúvidas, suas sugestões. Todas vão entrar na fila, serão resolvidas e publicadas na sequência.

A solução de hoje um problema ao qual fui submetido recentemente. Um avaliador pediu pra eu fazer um programa que validasse a abertura e fechamento de parênteses, colchetes e chaves.

(mais…)

std::pair x std::tuple

std::pair já existe há um bom tempo em C++, é a estrutura de dados que recupera os dados de um std::map através de iterators. Já std::tuple foi adicionado no C++11 e apesar de armazenar a mesma coisa é uma classe muito mais completa. Vamos conhecer a diferença entre os dois.

(mais…)

4 Formas de Loops For em C++

Loop é uma construção básica em uma linguagem de programação estruturada, e o loop for uma das formas mais comuns. Em C++ temos 5 formas de implementar loops for.

(mais…)