Estou trabalhando em um projeto C ++ em que tenho várias funções matemáticas que escrevi inicialmente para usar como parte de uma classe. Enquanto escrevia mais código, porém, percebi que precisava dessas funções matemáticas em todo lugar.
Onde é o melhor lugar para colocá-los? Digamos que eu tenho isso:
class A{
public:
int math_function1(int);
...
}
E quando escrevo outra aula, não posso (ou pelo menos não sei como) usá-lo math_function1
nessa outra aula. Além disso, percebi que algumas dessas funções não estão realmente relacionadas à classe A. Elas pareciam estar no começo, mas agora posso ver como são apenas funções matemáticas.
Quais são as boas práticas nesta situação? No momento, eu os copio e colo nas novas classes, o que, com certeza, é a pior prática.
static
palavra - chave?Respostas:
O C ++ pode ter funções não-método muito bem, se elas não pertencerem a uma classe, não as coloque em uma classe, apenas as coloque no escopo de namespace global ou outro
fonte
math_function1(42)
pode chamar um membro da classe atual;special_math_functions::math_function1(42)
está claramente chamando uma função independente). Dito isto,::math_function(42)
fornece a mesma desambiguação.// optional
. Tempere de acordo com o gosto.Depende de como o projeto está organizado e que tipo de padrões de design você está usando, assumindo que este seja um código estritamente utilitário, você tem as seguintes opções:
Observe que a primeira opção será a melhor aposta e as três seguintes são de utilidade limitada. Dito isso, você pode encontrar apenas devido a programadores de C # ou Java realizarem algum trabalho em C ++ ou se você trabalhar em código C # ou Java em que o uso de classes é obrigatório.
fonte
Como você já disse, copiar e colar o código é a pior forma de reutilização de código. Se você possui funções que não pertencem a nenhuma de suas classes ou podem ser usadas em vários cenários, o melhor lugar para colocá-las seria uma classe auxiliar ou de utilidade. Se eles não usarem nenhum dado de instância, eles poderão se tornar estáticos, portanto, você não precisará criar uma instância da classe de utilitário para usá-lo.
Consulte aqui para obter uma discussão sobre funções-membro estáticas no C ++ nativo e aqui para classes estáticas no C ++ gerenciado. Você pode usar essa classe de utilitário onde quer que cole seu código.
No .NET, por exemplo, coisas como
Min()
eMax()
são fornecidas como membros estáticos naSystem.Math
classe .Se todas as suas funções estão relacionadas à matemática e você também gostaria de ter uma
Math
classe gigantesca , convém dividi-la ainda mais e ter classes comoTrigonometryUtilities
,EucledianGeometryUtilities
e assim por diante.Outra opção seria colocar a funcionalidade compartilhada em uma classe base das classes que exigem essa funcionalidade. Isso funciona bem, quando as funções nas perguntas precisam operar com dados da instância, no entanto, essa abordagem também é menos flexível se você deseja evitar herança múltipla e se ater apenas a uma classe base, porque você estaria "esgotando" sua única base classe apenas para obter acesso a algumas funcionalidades compartilhadas.
fonte
Desambique o termo "função auxiliar". Uma definição é uma função de conveniência que você usa o tempo todo apenas para realizar algum trabalho. Eles podem viver no namespace principal e ter seus próprios cabeçalhos, etc. A outra definição de função auxiliar é uma função de utilitário para uma única classe ou família de classes.
Agora
isPrinter
está disponível para qualquer código, incluindo seu cabeçalho, masprint_alignment_page
requer umausing namespace printer_utils::Xerox;
diretiva. Pode-se também referi-lo comopara ser mais claro.
O C ++ STL possui o
std::
namespace que cobre quase todas as suas classes e funções, mas os divide categoricamente em mais de 17 cabeçalhos diferentes, para permitir que o codificador obtenha os nomes das classes, nomes de funções etc. fora do caminho, se quiserem escrever próprios.De fato, NÃO é recomendável usar
using namespace std;
em um arquivo de cabeçalho ou, como costuma ser feito, como a primeira linha dentromain()
.std::
tem 5 letras e muitas vezes parece uma tarefa anterior à função que se deseja usar (especialmentestd::cout
estd::endl
!), mas serve a um propósito.O novo C ++ 11 possui alguns sub namespaces para serviços especiais, como
que pode ser trazido para uso.
Uma técnica útil é a composição do espaço para nome . Um define um espaço para nome personalizado para armazenar os espaços para nome que você precisa para seu
.cpp
arquivo específico e usa-o em vez de váriasusing
instruções para cada coisa em um espaço para nome que você possa precisar.Essa técnica limita a exposição ao todo
std:: namespace
( é grande! ) E permite escrever código mais limpo para as linhas de código mais comuns que as pessoas escrevem com mais frequência.fonte
Você pode colocá-lo em uma função de modelo para disponibilizá-lo para diferentes tipos de números inteiros e / ou flutuantes:
Você também pode criar tipos personalizados simples que representam, por exemplo, grandes números ou números complexos, sobrecarregando os operadores relevantes para o seu tipo personalizado, para torná-los compatíveis com os modelos.
fonte