Eu gosto de usar esqueletos, ou seja, aqueles arquivos de modelo. Eles me ajudam a lembrar de coisas que normalmente precisamos e tambem deixam o codigo com uma cara homogenea.Mas eu nao gosto de esqueletos mortos, daqueles que estao estaticos e nao podem ser mudados, ou que sao iguais para todos os projetos. Gosto de esqueletos vivos, que evoluem, sendo customizados para cada projeto conforme vao sendo usados e gosto tambem que eles estejam versionados no sistema de versionamento DO PROJETO EM QUESTAO.Costumo usar os seguintes esqueletos:header://*****************************************************************************// Version/Revision log :// ====================//$Log: $////*****************************************************************************#ifndef TODO_NAME_H_INCLUDED#define TODO_NAME_H_INCLUDED//################################# Includes ##################################//################################## Types ####################################//################################ Constants ##################################//############################## Public Variables #############################//############################# ForwardDeclarations ###########################//################################# Classes ###################################//####################### Public Function Declarations #########################endif // TODO_NAME_H_INCLUDED//************************* E n d F i l e ***************************** cpp://*****************************************************************************// Version/Revision log :// ====================//$Log: $////*****************************************************************************//################################# Includes ###################################include "TODO_NAME.h"//################################## Types ####################################//######################### Private Classes Declaration ######################//################################ Constants ##################################//############################# Private Variables #############################//############################## Public Variables #############################//############################# Private Functions #############################//###################### Private Classes Implementation #######################//###################### Public Classes Implementation ########################//##################### Public Functions Implementation #######################//-------------------------------------------------// Unit tests//-------------------------------------------------#ifdef UNIT_TESTS#include <iostream>#include <assert.h>using namespace std;int main (){ cout << "Unit Testing for TODO_NAME class" << endl; Logger::logTostdout(); cout << "Testing TODO" << endl; { assert(!"No UNITTESTS implemented yet!"); } cout << ">>>>>> Tests finished with no errors" << endl; return 0;}#endif//************************* E n d F i l e *****************************declaracao de classe://=============================================================================// Class: TODO_NAME// Remarks: TODO//=============================================================================class TODO_NAME{public: TODO_NAME() {} ~TODO_NAME() {}private: TODO_NAME(const TODO_NAME& x); // Hide copy ctor to avoid implicit calling TODO_NAME& operator=(const TODO_NAME& x); // Hide = operator to avoid implicit calling}; // End of class TODO_NAME Implementacao de clase://=============================================================================// Class: TODO_NAME//=============================================================================//-----------------------------------------------------------------------------// Method: TODO// Remarks: TODO//-----------------------------------------------------------------------------void TODO_NAME::TODO(TODO){ //TODO} Makefile:#*****************************************************************************# Version/Revision log :# ====================#$Log: $##*****************************************************************************all: <<TODO: Implement all target to build your items in the current dirclean: <<TODO: Implement clean target that undoes what all does...install: <<TODO: Implement install target that installs the itens created by all to the correct places.uninstall: <<TODO: Implement clean target that undoes EVERYTHING that install does....PHONY: all clean install uninstall Recentemente, em um treinamento sobre design patterns, apos apresentar o factory method, pedi ao pessoal que fizesse um programa que, usando uma hierarquia de classes pre-existente que definia uma abstracao para envio de arquivos, perguntasse ao usuario qual tipo de envio ele queria usar (entre FTP ou SMB) e enviasse um arquivo ficticio usando o objeto de envio correto.Para clarear a coisas, a abstracao de envio e a hierarquia de classes correspondente era algo do tipo:class FileSender{public: virtual sendFile(string filename, string destination) = 0;};class FTPFileSender: public FileSender{public: sendFile(string filename, string destination) {...}};class SMBFileSender: public FileSender{public: sendFile(string filename, string destination) {...}};Claro, a ideia era que usassem um factory method para a criacao dos objetos. E todos acertaram esta parte. Todos implementaram um metodo FileSender::create, estatico que fazia algum return new, criando objetos das classes filhas FTPFileSender ou SMBFileSender e retornando um FileSender* apontando para o objeto criado.Ate aqui 100%. O problema e que a maioria fez o seguinte:typedef enum {FTP, SMB} FileSenderType;FileSender::create(FileSenderType type){ switch(type) { case FTP: return new FTPFileSender; case SMB: return new SMBFileSender; default: //Log error and abort. }}void main(){ cout << "SMB ou FTP?" << endl; FileSenderType myType; // Alguma logica para ler resposta