C2084 - function already has a body - c++

I'm running into an error "C2084 - function 'void Pet::display(void)' already has a body". Error occurs on Dog.cpp file. Slightly confused about the issue. Any help would be appreciated.
Pet.h
#ifndef _PET_H_
#define _PET_H_
#include <string>
using namespace std;
enum Type { dog = 0, cat };
class Pet {
private:
string name, breed; // private local variables
Type type;
public:
Pet(string pet_name, string pet_breed, Type pet_type); // constructor
// accessor methods
string getName();
string getBreed();
Type getType();
virtual void display() {};
};
#endif // _PET_H_
Dog.h
#ifndef _DOG_H_
#define _DOG_H_
#include "Pet.h"
#include <string>
using namespace std;
class Dog : public Pet {
public:
Dog(string pet_name, string pet_breed, Type pet_type) : Pet(pet_name, pet_breed, pet_type) {
} // constructor
virtual void display() = 0;
};
#endif
Dog.cpp
#include "Dog.h"
#include "Pet.h"
#include <iostream>
void Pet::display() {
cout << "Name: " << name << endl;
cout << "Breed: " << breed << endl;
cout << "Type: Dog" << endl;
}

It seems that you wanted to define Dog::display and have forgotten to rename Pet to Dog:
void Dog::display() {
cout << "Name: " << name << endl;
cout << "Breed: " << breed << endl;
cout << "Type: Dog" << endl;
}
Also remove " = 0" from:
virtual void display() = 0;
in "Dog.h".
In "Pet.h" file having " = 0" after function prototype is ok, it means that you shouldn't instantiate the Pet class directly (Abstract class).

In Pet.h you already have a body defined for display(), which does nothing.
In Pet.h:
class Pet {
/* other class members */
virtual void display() {}; // Here is your virtual function with an empty body.
};
In Dog.h:
class Dog : public Pet {
/* other class members */
virtual void display() = 0; // This pure virtual function which is inheriting from Pet which is not purely virtual.
};
Swap the two around.
Make Pet's virtual void display() = 0, i.e. a pure virtual function.
Make Pet's virtual void display(), i.e. a virtual function which you are already implementing in Dog.cpp.
Solution:
In Pet.h:
class Pet {
/* other class members */
virtual void display() = 0; // Make this a pure virtual function. It does not have an implementation.
};
In Dog.h:
class Dog : public Pet {
/* other class members */
virtual void display(); // This virtual function is implemented in Dog.cpp.
};

You are declaring the method display pure virtual in the class Dog which is derived from another class Pet. But the Pet class already has a concrete method called display. That' why you get this error.
Declare display as pure virtual in the Pet class and then give a concrete implementation in its child class Dog.

Related

Struggling with error message undefined reference to `Fish::Fish(std::string)'

I have this UML Diagram and I have written the code below but I am struggling with an error message
However, while compiling and linking, I got an error
/tmp/cc9oQaPX.o: In function `main':
main.cpp:(.text+0x8c): undefined reference to `Fish::Fish(std::string)'
main.cpp:(.text+0xe5): undefined reference to `Cat::Cat(std::string)'
main.cpp:(.text+0x116): undefined reference to `Fish::Fish()'
main.cpp:(.text+0x158): undefined reference to `Cat::Cat()'
collect2: error: ld returned 1 exit status
#include <iostream>
using namespace std;
class Animal // define base class
{
protected:
int legs; // base class properties
public:
Animal(int legNumbers) // set values of leg
{
legNumbers = legs; // set values of leg
}
virtual void eat() = 0; // method of base class
virtual void walk() {}; // method of base class
};
class Pet // define the pet class
{
protected:
string name; // set properties of pet class
public:
virtual string getName(); // define method
virtual string setName(string name); // set name values
virtual void play() // define play method
{
cout << " garfield is playing now." << endl; // out values
}
};
class Spider :public Animal //child class inherit base class
{
public:
Spider() :Animal(8) // spider class inherit animal class
{
cout << "animals with " << legs << " legs is walking. " << endl;
}
virtual void eat() // define virtual method
{
cout << "spider is eating now. " << endl;
}
};
class Cat :public Pet, public Animal // cat inherit two classes
{
public:
Cat(string name); // set name method
Cat();
virtual void play() // define method
{
cout << name << " is playing now. " << endl;
}
virtual void eat(); // define method here
};
class Fish : public Pet, public Animal // fish inherit two method
{
public: // define public members
Fish(string name);
Fish();
virtual void play()
{
cout << name << " is playing now. " << endl;
}
virtual void eat(); // method here
void walk()
{
cout << " Fish cannot walk " << endl; // output the values
}
};
string Pet::getName() // get name value from parent class
{
return string();
}
string Pet::setName(string name)
{
return string();
}
int main(int argc, char* argv[]) // define main method
{
Fish* f = new Fish("Jaws");
Cat* c = new Cat("Tenkir");
Animal *a = new Fish();
Animal* e = new Spider();
Pet* p = new Cat();
f->play();
c->play();
e->eat();
e->walk();
a->walk();
p->play();
return 0;
}
This is right code.
Firstly, you didn't defined the constructors for Cat an Fish
But that wasn't the only problem.
Your functions walk, eat, play need to be override. And eat() has to have a block, becuase in the base class (Animal) is deleted, like eat() = 0;
#include <iostream>
using namespace std;
class Animal // define base class
{
protected:
int legs; // base class properties
public:
Animal(int legNumbers) // set values of leg
{
legs = legNumbers; // set values of leg
}
virtual ~Animal() {}
virtual void eat() = 0; // method of base class
virtual void walk() {}; // method of base class
};
class Pet // define the pet class
{
protected:
string name; // set properties of pet class
public:
virtual string getName(); // define method
virtual void setName(string name); // set name values
virtual void play() // define play method
{
cout << " garfield is playing now." << endl; // out values
}
};
string Pet::getName() // get name value from parent class
{
return this->name;
}
void Pet::setName(string name)
{
this->name = name;
}
class Spider :public Animal //child class inherit base class
{
public:
Spider() :Animal(8) // spider class inherit animal class
{
cout << "animals with " << legs << " legs is walking. " << endl;
}
virtual void eat() // define virtual method
{
cout << "spider is eating now. " << endl;
}
};
class Cat :public Pet, public Animal // cat inherit two classes
{
public:
Cat(string name)
:Animal(4)
{
this->setName(name);
} // set name method
Cat():Animal(4){}
~Cat() override {}
virtual void play() override // define method
{
cout << name << " is playing now. " << endl;
}
virtual void eat() override {} // define method here
};
class Fish : public Pet, public Animal // fish inherit two method
{
public: // define public members
Fish(string name)
:Animal(0)
{
this->setName(name);
}
Fish():Animal(0){}
~Fish() override {}
virtual void play() override
{
cout << name << " is playing now. " << endl;
}
virtual void eat() override {} // method here
void walk() override
{
cout << " Fish cannot walk " << endl; // output the values
}
};
int main(int argc, char* argv[]) // define main method
{
Fish* f = new Fish("Jaws");
Cat* c = new Cat("Tenkir");
Animal *a = new Fish();
Animal* e = new Spider();
Pet* p = new Cat();
f->play();
c->play();
e->eat();
e->walk();
a->walk();
p->play();
return 0;
}

How to access to superclass functions from a subclass object

Is there a way to access superclass methods from a subclass?
I made Apple class as a subclass of Fruit class, but I can not access to setName function in Fruit class from an object of Apple class.
Could you give me any advice?
#include <iostream>
#include <string>
using namespace std;
class Fruit {
public:
Fruit(string str)
{
cout << "Fruit class" << endl;
name = str;
cout << name << endl;
}
void setName(string str) {
name = str;
}
private:
string name;
};
class Apple:Fruit {
public:
Apple() :Fruit("apple"){
cout << "Apple class" << endl;
}
void setName(string str) {
name = str;
}
};
int main()
{
Apple apple;
apple.setName("Orange"); //I can not access to setName function from apple
return 0;
}
Use public inheritance like this:
class Apple : public Fruit
The default visibility for class is private if it's not specified. That is why you're not able to access the public members of the base class because they're now private due to their private visibility.
Contrary to a class, the default visibility for a struct is public i.e.:
struct Base {};
struct Derived : Base {}; // public inheritance
In your code, the overridden setName() method in the derived class is redundant as it cannot manipulate the private data member name directly. You'll have to use the base class method to set the name in your overridden method. As of now, you're not doing anything else in that method so you don't need it.
Here's your working code (live):
#include <iostream>
#include <string>
using namespace std;
class Fruit {
public:
Fruit(string str)
{
cout << "Fruit class" << endl;
name = str;
cout << name << endl;
}
void setName(string str) {
name = str;
}
private:
string name;
};
class Apple : public Fruit { // public inheritance
public:
Apple() :Fruit("apple"){
cout << "Apple class" << endl;
}
// void setName(string str) { // Redundant!
// name = str; // `name` is not accessible here!
// }
};
int main()
{
Apple apple;
apple.setName("Orange"); // Accessible here
return 0;
}
For more relevant information, refer to this:
Difference between private, public, and protected inheritance
Your Apple class is using private inheritance (the default when the type of inheritance is not specified), so all of Fruit's public methods are private in Apple and thus are not accessible for main() to call. You need to use public inheritance instead to fix that.
Also, there is no need to re-implement setName() in Apple. The inherited setName() from Fruit will suffice, once it is inherited as a public method in Apple.
class Apple : public Fruit {
public:
Apple() : Fruit("apple"){
cout << "Apple class" << endl;
}
};
Use public inheritance
class Apple:public Fruit
in class Default is Private
class Apple:Fruit
is same as
class Apple:private Fruit
You made private here, So you can not access member of Fruit by object of Apple even if it is public.
class Apple:public Fruit
{
public:
Apple() :Fruit("apple")
{
cout << "Apple class" << endl;
}
};
Or if you want it is to private use like this
class Apple:Fruit
{
public:
Apple() :Fruit("apple")
{
cout << "Apple class" << endl;
}
void setName(string str)
{
Fruit::setName(str);
}
};
First, change class Apple to
class Apple: public Fruit
then, use this method
apple.Fruit::setname()

C++ virtual inheritance no member named in base class

I'm trying to solve an inheritance problem, where a derived class Snake inherits from LivingThing -> Animal -> Reptile, however, when I don't add virtual void crawl() to class LivingThing, the compiler says error: no member named 'crawl' in 'LivingThing'. Now I don't want to have to implement a virtual void in LivingThing which is specific for Snakes.
#include <iostream>
class LivingThing
{
public:
void breathe()
{
std::cout << "I'm breathing as a living thing." << std::endl;
}
virtual void crawl() {} //dont' want this
};
class Animal : virtual public LivingThing
{
public:
void breathe()
{
std::cout << "I'm breathing as an animal." << std::endl;
}
};
class Reptile : virtual public LivingThing
{
public:
void crawl()
{
std::cout << "I'm crawling as a reptile." << std::endl;
}
void breathe()
{
std::cout << "I'm breathing as a reptile." << std::endl;
}
};
class Snake : public Animal, public Reptile
{
public:
void breathe()
{
std::cout << "I'm breathing as a snake." << std::endl;
}
void crawl()
{
std::cout << "I'm crawling as a snake." << std::endl;
}
};
int main()
{
LivingThing *snake = new Snake();
snake->breathe();
snake->crawl();
system("pause");
return 0;
}
snake->crawl(); tries to access crawl through a LivingThing*, without a v-table reference, LivingThing* cannot call Snake::crawl.
In your current example you could just change the LivingThing pointer to be a Snake pointer.
In a more complex situation:
If you know that the pointer you're calling crawl on points to an object that is infact a Snake then you can static_cast the pointer.
if(Snake* snake = static_cast<Snake*>(livingThing))
snake->crawl();
If you have no guarantee that the living thing is actually a Snake and you have rtti available then you can use dynamic_cast.
if(Snake* snake = dynamic_cast<Snake*>(livingThing))
snake->crawl();
When you upcast object to it's base type, you can only use methods which are declared in this base class. So if you don't want to declare crawl method in your base type, you've to downcast your object before using this method:
LivingThing *creature = new Snake();
creature->breathe();
if(Snake* snake = dynamic_cast<Snake*>(creature)) snake->crawl();

Inheritance - Output using pointer [duplicate]

This question already has answers here:
Why do we need virtual functions in C++?
(27 answers)
Closed 6 years ago.
I've a question regarding inheritance
I've found this tutorial online, and was wondering why the output for "Dog" is actually "Animal print"
I understand that Animal pointer is pointing to the address of Dog,
but why isn't it printing "Dog print"?
Kindly help me out, I'm new to C++.
Below is the code:
#include <iostream>
using namespace std;
class Animal {
public:
void print();
};
void Animal::print() {
cout << "Animal print" << endl;
}
class Dog : public Animal {
public:
void print();
};
void Dog::print() {
cout << "Dog print" << endl;
}
int main() {
Dog h;
Animal *eptr = &h;
eptr->print();
eptr->Animal::print();
}
Output:
Animal print
Animal print
Here the child class object (dog) is pointed by a base class object (animal). But its limitation is only up to base class behavior.
#include <iostream>
using namespace std;
class Animal {
public:
virtual void print();
};
void Animal::print() {
cout << "Animal print" << endl;
}
class Dog : public Animal {
public:
void print();
};
void Dog::print() {
cout << "Dog print" << endl;
}
int main() {
Dog h;
Animal *eptr = &h;
eptr->print();
eptr->Animal::print();
}
You can use virtual function in order to access child class through base class object.

Polymorphic call through non-virtual method

I have a little problem with polymorphism. My simple code:
Animal.h
class Animal {
public:
Animal();
Animal(const Animal& orig);
virtual ~Animal();
virtual void get();
};
Animal.cpp
#include "Animal.h"
#include <iostream>
using namespace std;
Animal::Animal() {
cout << "Animal is born" << endl;
}
void Animal::get() {
cout << "get() from an Animal!" << endl;
}
Bird.h
class Bird : public Animal {
public:
Bird();
Bird(const Bird& orig);
virtual ~Bird();
void get();
};
Bird.cpp
#include "Bird.h"
#include <iostream>
using namespace std;
Bird::Bird() {
cout << "Bird is born" << endl;
}
void Bird::get() {
cout << "get() from a Bird!" << endl;
}
Chicken.h
#include "Bird.h"
class Chicken : public Bird {
public:
Chicken();
Chicken(const Chicken& orig);
virtual ~Chicken();
void get();
};
Chicken.cpp
#include "Chicken.h"
#include <iostream>
using namespace std;
Chicken::Chicken() {
cout << "Chicken is born" << endl;
}
void Chicken::get() {
cout << "get() from a Chicken!" << endl;
}
There is also a factory method returning an Animal* pointer to the concrete implementation based on input:
Factory.h
#include "Animal.h"
#include "Bird.h"
class Factory {
public:
Factory();
Factory(const Factory& orig);
virtual ~Factory();
Animal* generateAnimal();
Bird* generateBird();
};
Factory.cpp
#include "Factory.h"
#include "Animal.h"
#include "Bird.h"
#include "Chicken.h"
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
Animal* Factory::generateAnimal() {
string choice;
cout << "What do you want? 1-Animal, 2-Bird, 3-Chicken" << endl;
cin >> choice;
Animal* animal;
if (choice.at(0) == '1') {
cout << "You chose Animal" << endl;
animal = new Animal();
return animal;
} else if (choice.at(0) == '2') {
cout << "You chose Bird" << endl;
animal = new Bird();
return animal;
} else if (choice.at(0) == '3') {
cout << "You chose Chicken" << endl;
animal = new Chicken();
return animal;
} else {
cout << "Wrong input" << endl;
exit(1);
}
}
Bird* Factory::generateBird() {
string choice;
cout << "What do you want? 1-Animal, 2-Bird, 3-Chicken" << endl;
cin >> choice;
Bird* bird;
if (choice.at(0) == '2') {
cout << "You chose Bird" << endl;
bird = new Bird();
return bird;
} else if (choice.at(0) == '3') {
cout << "You chose Chicken" << endl;
bird = new Chicken();
return bird;
} else {
cout << "Wrong input" << endl;
exit(1);
}
}
I omitted ctors & dtors.
main.cpp
#include <cstdlib>
#include <iostream>
#include "Factory.h"
#include "Animal.h"
#include "Bird.h"
#include "Chicken.h"
using namespace std;
int main(int argc, char** argv) {
Factory factory;
Animal* animal = factory.generateAnimal();
animal->get();
return 0;
}
The concrete implementation of an Animal class is resolved during runtime.
It's obvious, that removing the virtual keyword from Animal class results in calling Animal implementation of get() method, whether animal* points to Bird or Chicken.
What do you want? 1-Animal, 2-Bird, 3-Chicken
3
You chose Chicken
Animal is born
Bird is born
Chicken is born
get() from an Animal!
It's also obvious, that calling the virtual get() method results in polymorphic call to the concrete subclass.
What concerns me is this situation:
Instead of
Animal* animal = factory.generateAnimal();
animal->get();
we have
Bird* bird = factory.generateBird();
bird->get();
We have a pointer to Bird class, in which the get() method is NOT declared virtual. The output is:
What do you want? 1-Animal, 2-Bird, 3-Chicken
3
You chose Chicken
Animal is born
Bird is born
Chicken is born
get() from a Chicken!
How does it happen, that call to non-virtual function results in virtual call to the subclass?
Is "virtualism" inherited? If it is, is it somehow possible to perform a non-virtual call to the pointer class, instead of implementation class?
A virtual method remains virtual in inherited classes even if you don't specify the virtual keyword. Actually in C++11 you have a way to specify that method is overridden:
class Bird {
void get() override;
}
You can even specify the virtual keyword on overridden methods just to remember it yourself but you can't "remove" the dynamic dispatch of the method.
The only thing you are allowed to do is to choose the implementation by specifying it:
Bird *bird = new Bird();
bird->Animal::get();
We have a pointer to Bird class, in which the get() method is NOT virtual.
That's wrong. It is virtual. Virtual functions cannot be made non-virtual by derived classes. The virtual keyword is just optional there, but it has no effect.
In short, yes, virtual is "inherited". In other words, you can't "change it back" from virtual to non-virtual when you inherit from a base-class. That would make the system very fragile to typos (forget virtual, and all of a sudden you call a different member depending on which route you came to the object).
Say you have a class hierarchy
class A{
void f();
};
class B : public A{
void f();
};
class C : public B{
void f();
};
\\...
class O : public N{
void f();
};
class P : public O{
virtual void f();
};
class Q : public P{
virtual void f();
};
class R : public Q{
void f();
};
\\...
class Z : public Y{
void f();
};
As soon as, traversing the hierarchy, a member is declared to be virtual, it will be so for further derived classes too. In case you are wondering, there is no way for making Z::f() non-virtual if Q::f() is virtual.
What this mean is explained in this code:
Z z;
A& a = z;
O& o = z;
P& p = z;
Q& q = z;
Z& z = z;
a.f(); //calls A::f()
o.f(); //calls O::f()
p.f(); //calls Z::f()
q.f(); //calls Z::f()
z.f(); //calls Z::f()
z.A::f(); //calls A::f()
z.R::f(); //calls R::f()
of course this assumes that O::f() is overridden.
See also my answer to a related question.