Inheriting a Protected Field from a Base Class

I'm trying to implement my java assignment (it's working in java) to C++ but when I tried to inherit from the Animal class, Crocodile class' constructor says "class 'Crocodile' does not have any field named 'name'". How can I fix this problem. I saw that they're using templates but I don't understand the point.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  
#include <iostream>
#include <string>

class Predator
{
    virtual std::string hunt() = 0;
};

class Walker : public Predator
{
    virtual std::string walk() = 0;
};

class Flyer : public Predator
{
    virtual std::string fly() = 0;
};

class Swimmer : public Predator
{
    virtual std::string swim() = 0;
};

class Animal
{
protected:
    std::string name;
public:
    std::string getName() {return name;}
    void setName(std::string name) {this->name = name;}
    
    Animal() : Animal {"Unknown Name"} {}
    Animal(std::string name) : name {name} {}
    
    std::string hunt() {return "";}
    std::string swim() {return "";}
    std::string walk() {return "";}
    std::string fly() {return "";}
};

class Crocodile : public Animal, public Walker, public Swimmer
{
public:
    std::string swim() override 
    {
        return " swims fast in water.";
    }
    
    std::string walk() override 
    {
        return " walks slow on land";
    }
    
    std::string hunt() override 
    {
        return " hunts on land and in water.";
    }
    
    Crocodile() : Crocodile{"Unknown name"} {}
    Crocodile(std::string) : name {name} {}
    
    
};

int main()
{
    
    return 0;
}
You can not use the member initializer list to initialize members of a base class.

Either set the member in the constructor body

 
Crocodile(std::string name) { this->name = name; }

or use the member initializer list to pass the name to the Animal constructor

 
Crocodile(std::string name) : Animal(name) {}

I would recommend the latter.
Try:

 
Crocodile(const std::string& nam) : Animal{ nam } {}


Note L31 - setName(). Either pass by const ref or use a std::move when setting name.

 
void setName(const std::string& nam) {name = nam;}


or
 
void setName(std::string name) {name = std::move(name);}


PS. Also note that member functions (such as getters) that don't change member data should be marked as const:

Last edited on
Not sure what the exercise is asking, but consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <string>

class Animal {
private:
	std::string name { "Unknown Name" };

public:
	virtual std::string walk() const = 0;
	virtual std::string fly() const = 0;
	virtual std::string swim() const = 0;
	virtual std::string hunt() const = 0;
	virtual std::string type() const = 0;

	std::string getName() const {
		return name;
	}

	void setName(const std::string& nam) {
		name = nam;
	}

	Animal() {}
	Animal(const std::string& nam) : name { nam } {}
	virtual ~Animal() {}
};

class Crocodile : public Animal {
public:
	using Animal::Animal;

	std::string type() const override {
		return "Crocodile";
	}

	std::string swim() const override {
		return " swims fast in water.";
	}

	std::string walk() const override {
		return " walks slow on land.";
	}

	std::string hunt() const override {
		return " hunts on land and in water.";
	}

	std::string fly() const override {
		return " cannot fly.";
	}
};

class Tiger : public Animal {
public:
	using Animal::Animal;

	std::string type() const override {
		return "Tiger";
	}

	std::string swim() const override {
		return " swims good in water.";
	}

	std::string walk() const override {
		return " runs fast on land.";
	}

	std::string hunt() const override {
		return " hunts on land and in water.";
	}

	std::string fly() const override {
		return " cannot fly.";
	}
};

void display(const Animal& an) {
	std::cout << "For " << an.getName() << '\n';
	std::cout << " is a " << an.type() << '\n';
	std::cout << an.fly() << '\n';
	std::cout << an.swim() << '\n';
	std::cout << an.walk() << '\n';
	std::cout << an.hunt() << '\n';
}

int main() {
	const auto c { Crocodile("ticktock") };
	const auto t { Tiger("tigger") };

	display(c);
	display(t);
}


which displays:


For ticktock
 is a Crocodile
 cannot fly.
 swims fast in water.
 walks slow on land.
 hunts on land and in water.
For tigger
 is a Tiger
 cannot fly.
 swims good in water.
 runs fast on land.
 hunts on land and in water.

Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <string>

class Predator
{
    public:
        // A class with a virtual function should have a virtual or protected destructor
        // https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rh-dtor
        virtual ~Predator() {}

        virtual std::string hunt() = 0;
};

class Walker : public Predator { virtual std::string walk() = 0; };

class Flyer : public Predator { virtual std::string fly() = 0; };

class Swimmer : public Predator { virtual std::string swim() = 0; };

class Animal
{
    protected: std::string name;

    public:

        std::string getName() const { return name;} // const
        void setName( std::string name ) noexcept { this->name = std::move(name) ; }

        Animal( std::string its_name = "Unknown Name" ) noexcept : name { std::move(its_name) } {}
};

class Crocodile : public Animal, public Walker, public Swimmer
{
    public:

        // inherited constructor: https://www.stroustrup.com/C++11FAQ.html#inheriting
        using Animal::Animal ;

        virtual std::string swim() override { return " swims fast in water."; }
        virtual std::string hunt() override { return " hunts on land and in water."; }
        virtual std::string walk() override { return " walks slow on land."; }
};

int main()
{
    Crocodile anon ; std::cout << anon.getName() << '\n' ; // Unknown Name

    Crocodile alphy( "Alfy Gator" ) ; std::cout << alphy.getName() << '\n' ; // Alfy Gator
}

http://coliru.stacked-crooked.com/a/d1f980748d07d989
Thanks for helping, I thought that C++ is inheriting fields like java. But it's just letting the sub-class use it.
Topic archived. No new replies allowed.