Pergunta

Eu criei uma classe, chamada vir, com um movimento função:

class vir
{
public:
     vir(int a,int b,char s){x=a;y=b;sym=s;}
     void move(){}
};

(é derivado de uma classe com variáveis ??int x, int y, e sym carvão animal) Eu ter derivado de uma classe a partir deste, chamado subvir:

class subvir:public vir
{
public:
     subvir(int a,int b,char s){x=a;y=b;sym=s;}
     void move();
};
subvir::move()
{
     x++;
     return;
}

E, em seguida, eu criei uma série de vir, e colocar um subvir nele

subvir sv1(0,0,'Q');
vir vir_RA[1]={sv1};

Mas quando eu tento usar sv1.move ():

vir_RA [0] .Move ();

Ele usa o movimento vir ({}) em vez do movimento subvir ({x ++}). Eu tentei fazer sv1 a vir e vir_RA a vir, e ele funciona, e também funciona quando eu torná-los tanto subvir, mas eu preciso deles para ser diferente. Eu tentei fazer vir :: move () um puro virtual, mas depois eu recebo um erro que justifiquem a matriz. Alguém sabe como posso obter move () para o trabalho quando eu usá-lo a partir da matriz?

Foi útil?

Solução

Você precisa de uma matriz de ponteiros, neste caso, em vez de uma matriz de instâncias. Use vir * [] em vez de vir []

Outras dicas

Você está correndo em um problema chamado corte . Use uma matriz de ponteiros, ou algo como Boost.ptr_container .

A classe base deve ter funções virtual para você o que você quer, tornando estes pura irá resultar em uma classe base abstrata - algo que você não pode instanciar. No entanto, você ainda pode criar ponteiros / referências a classes base abstratas e atribuir objetos classe derivada para eles. Sua classe base é melhor representado como:

class vir
{
public:
     vir(int a,int b,char s){x=a;y=b;sym=s;}
     virtual void move(){}
};

Isso faz move da classe derivada virtual. No entanto a sua definição move carece de um valor de retorno e não irá compilar. Tente:

void subvir::move()
{
     x++;
     return;
}

Note que você precisa tanto ponteiros (como mencionado em outras respostas) ou referências a classes derivadas para ligação a dinâmica de trabalho. Assim, em vez de uma matriz de objetos vir, use uma matriz de ponteiros de classe de base:

vir* v[ 2 ] = { new subvir(0, 0, 'Q'), new subvir(10, -10, 'P') };

Você também deve f Do ler-se sobre as seguintes seções do C ++ FAQ Lite:

Duas coisas. A matriz é uma matriz de vir é tão claro que usa a vir :: movimento. mover () não é um método virtual.

Mas o mais importante é cortar. Você não pode colocar subclasses em uma matriz. Se sizeof vir! = Subvir sizeof, a matriz não vai alinhar corretamente. Atualmente eles são do mesmo tamanho. Mas o que acontece se eles não são.

Sim, basicamente, compilador não permite que subclasses em matrizes porque matrizes são inicializados firmemente para o tamanho do tipo, e subtipos tendem ser maior do que os pais e que iria levar a problemas se você pudesse inicializar matrizes com valores de subtipo. O que realmente acontece é compilador primeira matriz aloca N * tamanho (base_type) bytes. E, em seguida, ele copia tamanho (base_type) bytes de cada um dos inicialização objetos. se fossem de diferentes tipos, que iria ficar truncado, e coisas estranhas poderia acontecer em seu código.

Deixe-me consolidar as respostas anteriores.

Na verdade, existem duas questões aqui. Um está cortando. Você está inicializando uma série de VIRS com uma cópia de um subvir. Nesses casos, o compilador corta a parte vir para fora do subvir e copiá-lo para a matriz, assim que você realmente obter apenas vir objetos lá. Agora no seu caso particular, subvir não tem membros de dados adicionais além daquelas de vir, então corte é um pouco degenerada eo objeto vir se parece muito com um subvir. No entanto, vir e subvir são diferentes classes e o objeto nas extremidades da matriz por ser um objecto vir e não um objecto subvir disfarçado como Vir. Uma maneira a diferença entre os dois se manifestaria na prática, mesmo que ambos tinham os mesmos membros de dados, é se vir tinha funções virtuais sobrecarregados por subvir. Nesse caso, o ponteiro TabelaV no objecto na matriz apontaria para TabelaV de vir, não de subvir. Claro, seria ainda mais explícito se subvir foram para conter membros de dados adicionais não encontrados em vir.

A segunda questão é polimorfismo. No ponto de uso (a chamada para move ()) o compilador acha que você está chamando o método move () de um objeto do tipo vir (desde a matriz é uma matriz de VIRS). (O compilador é, naturalmente, correto em pensar assim devido ao corte, degenerada como pode ser neste caso.) Se tivesse sido realmente um objeto subvir como você intented, você poderia começar subvir :: move () chamado, fazendo movimento ( ) virtual em vir.

Para obter o comportamento desejado, você poderia usar uma matriz de ponteiros (mas então você estaria operando diretamente sobre sv1, não uma cópia do mesmo, a menos que você criou primeiro uma cópia e inicializado a matriz com um ponteiro para a cópia).

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