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