Pergunta

Eu tenho uma classe base com uma função virtual opcional

class Base {
    virtual void OnlyImplementThisSometimes(int x) {}
};

Quando eu compilar este eu recebo um aviso sobre o não utilizado param x. Existe alguma outra maneira que eu deveria ter implementado a função virtual? Tenho re-escrito assim:

class Base {
    virtual void OnlyImplementThisSometimes(int x) 
    {
        x = 0;
    }
};

Eu também tenho o problema de que, se eu não tomar cuidado, a subclasse I make pode implementar a função errada e então eu não percebe por causa da sobrecarga:. Por exemplo

class Derived : public Base {
    void OnlyImplementThisSometimes(int x, int y) { // some code }
};

Derived d;
Base *b = dynamic_cast<Base *>(&d);
b->OnlyImplementThisSometimes(x); // calls the method in the base class

O método de classe base foi chamado porque eu implementada a função derivada com um param "int y" mas não há nenhum aviso sobre isso. São essas armadilhas apenas comuns em C ++ ou ter eu entendi mal funções virtuais?

Foi útil?

Solução

Ignorando as questões de design que você pode contornar o aviso do compilador cerca de uma variável não utilizada, omitindo o nome da variável, por exemplo:

virtual void OnlyImplementThisSometimes(int ) { }

Equivocadamente implementar a assinatura do método errado ao tentar substituir a função virtual é apenas algo que você precisa ter cuidado com em C ++. Linguagens como C # contornar esta situação com a palavra-chave 'override'.

Outras dicas

Nós definimos um _unused macro como:

#define _unused(x) ((void)x)

Em seguida, defina a função como:

virtual void OnlyImplementThisSometimes(int x) { _unused( x );}

Isso não só mantém o compilador reclamando, mas faz com que seja óbvio para qualquer um manter o código que você não tenha esquecido x -. Você é intencionalmente ignorá-lo

Por defini-lo na classe base? Se a classe base não vai usar o método, em seguida, basta defini-lo como um método virtual em sua classe derivada.

Ou a implementação padrão pode lançar uma exceção

Se você fornecer uma implementação padrão de uma função virtual, que deve ser uma implementação correta para todas as classes derivadas que não substituem essa função. Se você não pode fornecer um correta implementação, em seguida, o meu conselho seria para fazer uma função virtual pura e deixar isso para a classe derivada para fornecer uma implementação. classes que não permitem que o método a ser chamado pode lançar uma exceção para garantir que ele não é usado por engano derivada.

Além de simplesmente omitir o nome da variável, em muitos compiladores você pode dizer ao compilador, que você está ciente de que é não utilizado e SHUTUP fazendo isto

int func(int x)
{
   (void) x;
}

Este é um pouco comum no meu código. Por exemplo, tenho classes que são desenhados para operação com uma só rosca e multi-threaded. Há uma série de rotinas e dados comuns. Coloquei tudo isso na classe base (que tem um par de puro virtual como bem).

Eu implementar duas funções vazias virtuais na classe base: init () e limpeza (). A única classe rosca derivada não impliment-los, mas o mulit-threaded se faz.

Eu tenho uma função fábrica criar o approprite classe derivada, em seguida, retornar um ponteiro. O código do cliente só sabe sobre o tipo de classe base e que chama Init () e Limpeza (). Ambos os cenários fazer a coisa certa.

É claro, pode haver outras sugestões boas sobre como fazer isso, mas essa expressão funciona bem para um monte de meu código.

Não é uma má prática e é uma expressão comum para especificar partes de uma classe que são opcionais para implementar.

Atualmente eu estou usando-o para um sistema de entrada do usuário, porque seria tedioso para um usuário dessa classe para implementar cada método único, mesmo que ele provavelmente não vai usá-lo de qualquer maneira.

class mouse_listener{
public:
    virtual ~mouse_listener() {}

    virtual void button_down(mouse_button a_Button) {}
    virtual void button_up(mouse_button a_Button) {}
    virtual void scroll_wheel(mouse_scroll a_Scroll) {}
    virtual void mouse_move_abs(math::point a_Position) {}
    virtual void mouse_move_rel(math::point a_Position) {}
};

Btw, se você sabe que sua classe base, nunca há qualquer necessidade de fazer dinâmico se -casts, ou seja, a partir de derivados de base.

Base *b = &d;

vai fazer tão bem, dynamic_cast<> deve preferivelmente ser usado quando você para baixo-cast, ou seja, da base à deriva:

if((Derived *d = dynamic_cast<Derived *>(b)) != 0)
{
  // use d
}

(E, claro, no caso de down-cast, static_cast<> normalmente funcionará bem.)

Tente isto:

class Base {
    virtual void OnlyImplementThisSometimes(int x) = 0;
};

Tem sido um tempo desde que eu o material feito assim, mas eu acredito que é como você declarar uma função virtual.

Além disso, como já foi dito, os nomes das variáveis ??são opcionais em declarações de função como esta.

A resposta mais simples para isso é mostrado abaixo:

class Base {
    virtual void OnlyImplementThisSometimes(int x) { x;}
};

Uma simples referência à variável que não faz absolutamente nada irá remover todas as advertências (de VC ++ no nível mais alto de qualquer maneira).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top