Question about Class Inheritance.

std:: cout << "Hello People!";

I have a question about class inheritance and more particularly about initialising them.
Let me give you an example to explain what I mean:

Let's say we have the three following classes

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
//BASE CLASS
class BaseClass
{
    private:
        string name;

    public:
        BaseClass();
        BaseClass(string n)
            { name = n; }
};

//DERIVED CLASS #1
class DerivedClassOne : public BaseClass
{
    private:
        string phoneNumber;

    public:
        DerivedClassOne(): BaseClass();
        DerivedClassOne(string n, string p) : BaseClass(n)
            { phoneNumber = p; }
};

//DERIVED CLASS #2
class DerivedClassTwo : public DerivedClassOne
{
    private:
        string address;

    public:
        DerivedClassTwo(): DerivedClassOne();
        DerivedClassTwo(string p, string a) : DerivedClassOne(p)
        { address = a; }
};


Now assuming that in the main function I get input such as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
    string name,
           phoneNum,
           address;

    cout << " Name: ";
    getline(cin, name);

    cout << "\n Phone number: ";
    getline(cin, phoneNum);

    cout << "\n Address: ";
    getline(cin, address);


    //CREATE OBJECT HERE


    return 0;
}


Is it possible to initialise a DerivedClassTwo object holding information
for both the name, phoneNum and address strings?


Thank you in advance for any answer and/or advice!

Have a good day/evening/morning!
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <string>
#include <iostream>

using namespace std;

//BASE CLASS
class BaseClass
{
    public:
        string name;


        BaseClass();
        BaseClass(string n)
            { name = n; }
};

//DERIVED CLASS #1
class DerivedClassOne : public BaseClass
{
    public:
        string phoneNumber;


        DerivedClassOne(): BaseClass() {};
        DerivedClassOne(string n, string p) : BaseClass(n)
            { phoneNumber = p; }
};

//DERIVED CLASS #2
class DerivedClassTwo : public DerivedClassOne
{
      

    public:
        string address;

        DerivedClassTwo() {};
        DerivedClassTwo(string n, string p, string a) : DerivedClassOne(n, p)
        { address = a; }
};


	

int main()
{
    string name,
           phoneNum,
           address;

    cout << " Name: ";
    getline(cin, name);

    cout << "\n Phone number: ";
    getline(cin, phoneNum);

    cout << "\n Address: ";
    getline(cin, address);

    DerivedClassTwo object(name, phoneNum, address);

    cout << "From DCTwo: " << object.name << " " << object.phoneNumber << " " << object.address;

    return 0;
}
It's certainly possible. Your setup is a bit wrong, perhaps a copy-paste typo.

DerivedClassTwo(string p, string a) : DerivedClassOne(p)
DerivedClassOne takes in a 2-arg constructor, not a 1-arg. You also never pass in the name to your DerivedClassTwo constructor.

Change both of those things, and you can get it to work.

Also, please use more descriptive variable names. Seldom should you use 1-letter names except for the standard "i, j, k, sometimes n" loop-counting variables.

1
2
DerivedClassTwo(string name, string phone_number, string address)
: DerivedClassOne(name, phone_number), address(address) {} 
Thank you for your answer Repeater!

So if I understood correctly: as many Derived classes as there are, as long as you put
the arguments for all classes constructors in DerivedClassX(...,...,...)?

Like this would also work with 5 consecutive derived classes?

So if I understood correctly: as many Derived classes as there are, as long as you put
the arguments for all classes constructors in DerivedClassX(...,...,...)?


Not necessary.

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
#include <string>
#include <iostream>

using namespace std;

//BASE CLASS
class BaseClass
{
    public:
        string name;


        BaseClass(){};
        BaseClass(string n)
            { name = n; }
};

//DERIVED CLASS #1
class DerivedClassOne : public BaseClass
{
    public:
        string phoneNumber;


        DerivedClassOne(): BaseClass() {};
        DerivedClassOne(string n, string p) : BaseClass(n)
            { phoneNumber = p; }
};

//DERIVED CLASS #2
class DerivedClassTwo : public DerivedClassOne
{
      

    public:
        string address;

        DerivedClassTwo(): DerivedClassOne() {};
        DerivedClassTwo(string n, string p, string a)
       {
             name = n;
             phoneNumber = p;
             address = a;
       }
};


	

int main()
{
    string name,
           phoneNum,
           address;

    cout << " Name: ";
    getline(cin, name);

    cout << "\n Phone number: ";
    getline(cin, phoneNum);

    cout << "\n Address: ";
    getline(cin, address);

    DerivedClassTwo object(name, phoneNum, address);

    cout << "From DCTwo: " << object.name << " " << object.phoneNumber << " " << object.address;

    return 0;
}

Thank you Ganado, I was not copy-pasting it but I was making up a short example to illustrate
my question hence the error, you're right!

Also thank you for the advice on variables, I'll try to fix this habit asap then.
@Repeater

Okay I've got it! Thanks for your time.
Out of curiosity, could you have the DerivedClassTwo constructor like this:

1
2
3
DerivedClassTwo(string name, string phoneNum, string address) :
DerivedClassOne(phoneNum) : BaseClass (name)
    { address = address; }


?
Actually I'm having a sort of issue now. You provided explanation with both the base class
and the derived classes having their variables defined publicly. However I need them define
privately.

The issue is that now, I can only initialise a DerivedClassTwo object so that it holds the variables
of DerivedClassOne and DerivedClassTwo since the BaseClass private variables have become
inaccessable.

Is there any faisable way of countering that? Or do I have to manually set the private variables
in BaseClass once the DerivedClassTwo object is created?
A Base Class is created before any Derived class. The member variable being private shouldn't affect your ability to initialize the variables with a constructor. Maybe I'm misunderstanding the question.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Base {
  public:
    Base(int a) : a(a) {}
  private:
    int a;
};

class Derived : public Base {
  public:
    Derived(int a, int b) : Base(a), b(b) {}

  private:
    int b;
};


If you want to Derived to be able to internally access Base's a, you need to make a be protected instead of private. Or, have a public or protected accessor.
To able to access a or b after the initialization to the general public, some sort of assessor "getter" function will be needed.

Ex:
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
class Base {
  public:
    Base(int a) : a(a) {}
  protected:
    int getA() { return a; }
  private:
    int a;
};

class Derived : public Base {
  public:
    Derived(int a, int b) : Base(a), b(b) {}
    int calculate_stuff()
    {
        return b + getA();
    }
  private:
    int b;
};

#include <iostream>

int main()
{
    Derived d(3, 2);
    std::cout << d.calculate_stuff() << std::endl;
}


Edit: Fixed my dumb typos
Last edited on
Okay this is interesting but I'll try to reformulate more clearly my question and illustrate it.

I have 3 classes like so:
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
class Base
{
    Protected:
        int base1;
        int base2;
        int base3;

    public:
        Base(int b1, int b2, int b3)
            {
                base1 = b1;
                base2 = b2;
                base3 = b3;
            }
};

class Derived : public Base
{
    private:
        int derived1;
        int derived2;

    public:
        Derived(int d1, int d2, int b1, int b2, int b3) : Base(b1, b2; b3)
            {
                derived1 = d1;
                derived2 = d2;
            }
};

class Thrid : public Derived
{
    private:
        int third1;
        int third2;
        int third3;

    public:
        Third(int t1, int t2, int t3, int d1, int d2) : Derived (d1, d2)
            {
                 third1 = t1;
                 third2 = t2;
                 third3 = t3;
            }
};



Now my main function looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main()
{
    int b1, b2, b3, d1, d2, t1; t2; t3;

    cin >> b1;
    cin >> b2;
    cin >> b3;

    cin >> d1;
    cin >> d2;

    cin >> t1;
    cin >> t2;
    cin >> t3;

//Option 1
    Third object(t1, t2, t3, d1, d2)
//object is initialised but without the variables b1, b2, b3.

//Option 2
    Third object(t1, t2, t3, d1, d2, b1, b2, b3)
//Object isn't initialised: error, the constructor is meant to take
//5 argument and there are 8..
};


So my question is: How do I initialise an object of the Third class with all the variables declared in main()?

Is there anything wrong with my constructors?

I might be doing/missing something really stupid and obvious yet i'm clueless..
You're having a bunch of argument mismatches. The number of items you pass into a constructor must match what the constructor is defined as.
Third(int t1, int t2, int t3, int d1, int d2) : Derived (d1, d2)
You are giving Derived 2x arguments, (d1, d2).
But Derived expects 5x arguments:
Derived(int d1, int d2, int b1, int b2, int b3)
See the problem?

Also,
Derived(int d1, int d2, int b1, int b2, int b3) : Base(b1, b2; b3)
Change the semi-colon to a comma.

If you want to be able to pass in every variable yourself to initialize Third, Derived, and Base, you could do something like this.
1
2
3
4
5
6
7
Third(int t1, int t2, int t3, int d1, int d2, int b1, int b2, int b3)
: Derived (d1, d2, b1, b2, b3)
            {
                 third1 = t1;
                 third2 = t2;
                 third3 = t3;
            }


Add more arguments to your Third constructor (as above), or create two different constructors, one for each situation you desire (a 5-arg constructor and an 8-arg constructor).
1
2
3
4
5
6
7
Third(int t1, int t2, int t3, int d1, int d2)
: Derived (d1, d2, 0, 0, 0)
            {
                 third1 = t1;
                 third2 = t2;
                 third3 = t3;
            }
Last edited on
Okay now it's crystal clear, that's exactly the answer I was looking for.

Thanks a lot for your time Ganado! Good day to you!
Yep you're welcome :)
Topic archived. No new replies allowed.