O meu código em C++ não funciona [RESOLVIDO]

1. O meu código em C++ não funciona [RESOLVIDO]

skjdeecedcnfncvnrfcnrncjvnjrnfvjcnjrjvcjrvcj
Londreslondres

(usa Parabola)

Enviado em 14/05/2024 - 12:07h

O meu código:
#include <iostream>

class FlyBehavior{
public:
virtual void fly() = 0;
};

class FlyWithWings: public FlyBehavior{
public:
void fly(){
std::cout << "I'm flying!!!\n";
};
};

class FlyNoWay: public FlyBehavior{
public:
void fly(){
std::cout << "I can't fly\n";
};
};

class QuackBehavior{
public:
virtual void quack() = 0;
};

class Quack: public QuackBehavior{
public:
void quack();
};

class Squeak: public QuackBehavior{
public:
void quack(){
std::cout << "Quack\n";
};
};

class MuteQuack: public QuackBehavior{
public:
void quack(){
std::cout << "Silence\n";
};
};

class Duck{
public:
FlyBehavior* flyBehavior;
QuackBehavior* quackBehavior;
void performQuack(){
quackBehavior->quack();
};
void swim();
virtual void display() = 0;
void performFly();
};

class MallardDuck: public Duck{
public:
MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
};
void display(){
std::cout << "I'm a real Mallard Duck\n";
};
};

int main(){
Duck* mallard = new MallardDuck;
mallard->performQuack();
mallard->performFly();
}


Ao tentar compilá-lo, apresenta este erro:
$ g++ main.cc
/usr/bin/ld: /tmp/ccq15Ryy.o: aviso: relocalização contra "_ZTV5Quack" em secção só de leitura ".text._ZN5QuackC2Ev[_ZN5QuackC5Ev]"
/usr/bin/ld: /tmp/ccq15Ryy.o: na função "main":
main.cc:(.text+0x40): undefined reference to `Duck::performFly()'
/usr/bin/ld: /tmp/ccq15Ryy.o: na função "Quack::Quack()":
main.cc:(.text._ZN5QuackC2Ev[_ZN5QuackC5Ev]+0x1b): undefined reference to `vtable for Quack'
/usr/bin/ld: aviso: a criar DT_TEXTREL num PIE.
collect2: error: ld returned 1 exit status



  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 15/05/2024 - 01:44h

Você apenas declarou Quack::quack(), sem a definir. Quando você cria um objeto di tipo Quack, dentro do construtor de MallardDuck(), você obriga o compilador a exigir que a função esteja definida, mesmo que não viesse a usá-la (mas você a usa, quando faz mallard->performQuack()).


... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)

3. MELHOR RESPOSTA

skjdeecedcnfncvnrfcnrncjvnjrnfvjcnjrjvcjrvcj
Londreslondres

(usa Parabola)

Enviado em 15/05/2024 - 09:53h


paulo1205 escreveu:

Você apenas declarou Quack::quack(), sem a definir. Quando você cria um objeto di tipo Quack, dentro do construtor de MallardDuck(), você obriga o compilador a exigir que a função esteja definida, mesmo que não viesse a usá-la (mas você a usa, quando faz mallard->performQuack()).


... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)


Defini as funções Quack::quack() e Duck::performFly(). Funcionou!

4. Re: O meu código em C++ não funciona [RESOLVIDO]

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 14/05/2024 - 12:08h

Desculpe, não consigo responder essa dúvida específica. Mas, se precisar de ajuda com comandos no Linux ou programação em NodeJS e React, estou aqui para ajudar!


5. Re: O meu código em C++ não funciona

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 14/05/2024 - 16:29h

Está faltando o corpo das funções membros dentro das classes.
Por exemplo, quando se declara uma classe com função pura virtual como a FlyBehavior::fly, vc está dizendo que a próxima classe derivada de FlyBehavior deve implementar obrigatoriamente a função membro fly. Além disso, o g++ as vezes buga quando uma função membro é virtual mas seu destrutor não é.
E também, quando vc sobrescreve a função fly na classe derivada vc deve usar o especificador override pra dizer que aquela função virtual foi sobrescrita da classe base.
Exemplo prático:

#include <iostream>

class FlyBehavior{
public:
//coloca destrutor virtual, isso acontece sempre que houver uma função virtual na classe
virtual ~FlyBehaviour(){}
função pura virtual, será definida na classe derivada
virtual void fly() = 0;
};

class FlyWithWings: public FlyBehavior{
public:
//definição do método puro virtual anterior, junto com especificador override
void fly() override {
std::cout << "I'm flying!!!\n";
};
};

class FlyNoWay: public FlyBehavior{
public:
//definição do método puro virtual anterior, junto com especificador override
void fly() override {
std::cout << "I can't fly\n";
};
};

Ver mais aqui:
https://en.cppreference.com/w/cpp/language/override

Já no seguinte código:
class Duck{
public:
virtual ~Duck(){} <--definindo o construtor padrão aqui
FlyBehavior* flyBehavior;
QuackBehavior* quackBehavior;
void performQuack(){
quackBehavior->quack();
};
void swim();
virtual void display() = 0;
void performFly() } <--faltou definir o código da função, coloquei como vazio
};


class MallardDuck: public Duck{
public:
MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
};
//não esqueça de liberar a memoria do quackBehaviour e flyBehaviour no destrutor

//adicionei o override pra indicar que o display é sobrescrito da classe base
void display() override{
std::cout << "I'm a real Mallard Duck\n";
};
};



https://nerdki.blogspot.com/ acessa ai, blog dedicado Paranóia!
https://github.com/cpusam com o bug fix vem a perfeição!


6. Re: O meu código em C++ não funciona

skjdeecedcnfncvnrfcnrncjvnjrnfvjcnjrjvcjrvcj
Londreslondres

(usa Parabola)

Enviado em 14/05/2024 - 18:41h

SamL escreveu:

Está faltando o corpo das funções membros dentro das classes.
Por exemplo, quando se declara uma classe com função pura virtual como a FlyBehavior::fly, vc está dizendo que a próxima classe derivada de FlyBehavior deve implementar obrigatoriamente a função membro fly. Além disso, o g++ as vezes buga quando uma função membro é virtual mas seu destrutor não é.
E também, quando vc sobrescreve a função fly na classe derivada vc deve usar o especificador override pra dizer que aquela função virtual foi sobrescrita da classe base.
Exemplo prático:

#include <iostream>

class FlyBehavior{
public:
//coloca destrutor virtual, isso acontece sempre que houver uma função virtual na classe
virtual ~FlyBehaviour(){}
função pura virtual, será definida na classe derivada
virtual void fly() = 0;
};

class FlyWithWings: public FlyBehavior{
public:
//definição do método puro virtual anterior, junto com especificador override
void fly() override {
std::cout << "I'm flying!!!\n";
};
};

class FlyNoWay: public FlyBehavior{
public:
//definição do método puro virtual anterior, junto com especificador override
void fly() override {
std::cout << "I can't fly\n";
};
};

Ver mais aqui:
https://en.cppreference.com/w/cpp/language/override

Já no seguinte código:
class Duck{
public:
virtual ~Duck(){} <--definindo o construtor padrão aqui
FlyBehavior* flyBehavior;
QuackBehavior* quackBehavior;
void performQuack(){
quackBehavior->quack();
};
void swim();
virtual void display() = 0;
void performFly() } <--faltou definir o código da função, coloquei como vazio
};


class MallardDuck: public Duck{
public:
MallardDuck(){
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
};
//não esqueça de
 
liberar a memoria do quackBehaviour e flyBehaviour no destrutor

//adicionei o override pra indicar que o display é sobrescrito da classe base
void display() override{
std::cout << "I'm a real Mallard Duck\n";
};
};



https://nerdki.blogspot.com/ acessa ai, blog dedicado Paranóia!
https://github.com/cpusam com o bug fix vem a perfeição!


Coloquei os destruidores e o override.

Continua com o erro:
/usr/bin/ld: /tmp/cctIBG02.o: aviso: relocalização contra "_ZTV5Quack" em secção só de leitura ".text._ZN5QuackC2Ev[_ZN5QuackC5Ev]"
/usr/bin/ld: /tmp/cctIBG02.o: na função "main":
main.cc:(.text+0x40): undefined reference to `Duck::performFly()'
/usr/bin/ld: /tmp/cctIBG02.o: na função "Quack::Quack()":
main.cc:(.text._ZN5QuackC2Ev[_ZN5QuackC5Ev]+0x1b): undefined reference to `vtable for Quack'
/usr/bin/ld: aviso: a criar DT_TEXTREL num PIE.
collect2: error: ld returned 1 exit status





  



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts