Question on constructors in Inheritance

  • Thread starter yungman
  • Start date
In summary, the object of the derived class MoreTrouble has its own member variable message, which is different from the member variable message of the base class Trouble.
  • #1
yungman
5,755
293
I am reviewing Inheritance again as Ivor book gets into exception using class object of base and derived class. I gone through a few books and still don't quite understand. This is the program I wrote to ask the questions:
C++:
#include<iostream>
using namespace std;
class BaseClass1
{public:
    int a, b;
    BaseClass1() { a = 0; b = 0; }
    void BaseFunc11() {}
    void BaseFunc21() {}
};
class DerivedClass1 : public BaseClass1
{public:
    int c;
    DerivedClass1() : BaseClass1(){ c = 0;}
    void DerivedFunc11(){}
};
//I want to confirm that
//1) OBJECT of DerivedClass has it's own member variables a, b c.
//2) OBJECT of DerivedClass has it's own BaseFunc21(), BaseFunc12()
//     and DerivedFunc11().class BaseClass2
{public:
    int a, b;
    BaseClass2() { a = 0; b = 0; }
    BaseClass2(int A, int B) { a = A, b = B; }
    void BaseFunc21() {}
    void BaseFunc22() {}
};
class DerivedClass2 : public BaseClass2
{public:
    DerivedClass2() : BaseClass2(a, b) { }
    DerivedClass2(int b, int c) : BaseClass2(a, b) { }//How many b do we have?
    void DerivedFunc21(){}
};
//Object of DerivedClass2 has member variable a, b and c
//Object of DerivedClass2 has member function BaseFunc21,
//BaseFunc22 and DerivedFunc21.
//b is being declared in DerivedClass2(int b, int c) AND BaseClass2(a, b)
//What does this mean? how many member variable b the DerivedClass2 object has?

int main()
{
    DerivedClass1 DC1;
    DerivedClass2 DC2;
}

1) I want to verify when saying the object of derived class inheriting member variables and member functions, this means the object of derived class has it's OWN member variables a, b and c. Has it's OWN member function BaseFunc21(), BaseFunc12() and DerivedFunc11().

2) The second question is more confusing to me as shown with BaseClass2 and DerivedClass2:
Line 33 shows DerivedClass2(int b, int c) : BaseClass2(a, b) { }. Notice variable b is common name defined in DerivedClass2 and in BaseClass2. How many b do I have in the object of derived class? b belongs to DerivedClass2 or BaseClass2?

For default constructor, it's easy to understand. Line 13 DerivedClass1() : BaseClass1(){ c = 0;} just simply combine both constructors to give a=0, b=0 and c=0. But for constructor with arguments and variable with the same name, it get's confusing. which one should I choose.

For member function with the same name, you can declare virtual in the base member function and the program will know if it's the derived class calls the function, it will just go to the function of the derived class.

thanks
 
Technology news on Phys.org
  • #2
While I am waiting for you guys to comfirm, I am hot on the trod verifying what I ask in the OP. I think I am correct on the first part that the derived class object has it's COMPLETE set of member variables of it's own.

From stepping through each object of the derived classes and the base class have different memory address for c-string str as shown. I even change the content of the c-string step by step to proof the other two keep the original content.

This is my program that I have a base class Trouble, then a derived class MoreTrouble. Then a derived class BigTrouble derived from MoreTrouble. I stepped and put the addresses of both c-string str and message in the comment of the line of code. You can see they are all different from each other.

C++:
//Show derived class contain variables of Base class of it's own
#include<iostream>
#include<string>
#include<string_view>
#include<cstring>
using namespace std;
const int csize = 51;
class Trouble
{ public:
    char message[csize];
    Trouble(const char* str)//str = 0x00609B48
       { strncpy_s(message, csize, str, csize);}//message = 0x0053F870
    void getMessage(){}
    ~Trouble() = default;//Base classes must have virtual des.
};
class MoreTrouble : public Trouble
{ public:
    MoreTrouble(const char*str)//19, 19,
       : Trouble(str) //11, 11, 25, //str=0x00609B30
       {strncpy_s(message,csize,str,csize);}// message=0x0053F834
    ~MoreTrouble() { cout << " Destructor MoreTrouble.\n"; }
};
class BigTrouble : public MoreTrouble
{ public:
    BigTrouble(const char*str)//25,
       : MoreTrouble(str) //18, 32, str =0x00609B74
       {strncpy_s(message,csize,str,csize);}//message=0x0053F7F8
    ~BigTrouble() { cout << " Destructor BigTrouble.\n"; }
};
int main()
{    Trouble trouble(" Theres trouble");//11,
    MoreTrouble moreTrouble(" More    trouble"); //18,
    BigTrouble bigTrouble(" Real big trouble");//24,
    cout << trouble.message<<",\t&trouble.message = "<<
        &trouble.message<<"\n";//&trouble.message = 0x00609B48
    cout << moreTrouble.message<<",\t&moreTrouble.message = "<<
        &moreTrouble.message<<"\n";//&moreTrouble = 0x0053F834
    cout << bigTrouble.message <<",\t&bigTrouble.message = "<<
        &bigTrouble.message<<"\n\n";//&bigTrouble.message = 0x0053F7F8
  
    strncpy_s(trouble.message,csize," New   trouble",csize);
    cout << trouble.message << ",\t\t&trouble.message = "<<
        &trouble.message << "\n";//&trouble.message = 0x00609B48
    cout << moreTrouble.message << ",\t&moreTrouble.message = " <<
        &moreTrouble.message << "\n";//&moreTrouble = 0x0053F834
    cout << bigTrouble.message << ",\t&bigTrouble.message = " <<
        &bigTrouble.message << "\n\n";//&bigTrouble.message = 0x0053F7F8
  
    strncpy_s(moreTrouble.message,csize," New moreTrouble",csize);
    cout << trouble.message << ",\t\t&trouble.message = " <<
        &trouble.message << "\n";//&trouble.message = 0x00609B48
    cout << moreTrouble.message << ",\t&moreTrouble.message = " <<
        &moreTrouble.message << "\n";//&moreTrouble = 0x0053F834
    cout << bigTrouble.message << ",\t&bigTrouble.message = " <<
        &bigTrouble.message << "\n\n";//&bigTrouble.message = 0x0053F7F8
  
    strncpy_s(bigTrouble.message,csize," New bigTrouble",csize);
    cout << trouble.message << ",\t\t&trouble.message = " <<
        &trouble.message << "\n";//&trouble.message = 0x00609B48
    cout << moreTrouble.message << ",\t&moreTrouble.message = " <<
        &moreTrouble.message << "\n";//&moreTrouble = 0x0053F834
    cout << bigTrouble.message << ",\t&bigTrouble.message = " <<
        &bigTrouble.message << "\n\n";//&bigTrouble.message = 0x0053F7F8
}

this is the printout from running the program:
Trouble class.jpg

I even change the name str to str0 for Trouble class, str1 for MoreTrouble class and str2 for BigTrouble class. The result is the same running the program. So I still don't know what to make of str in the constructor of the derived class.

The program is working.
Thanks
 
  • #3
yungman said:
I am reviewing Inheritance again as Ivor book gets into exception using class object of base and derived class. I gone through a few books and still don't quite understand. This is the program I wrote to ask the questions:
C++:
#include<iostream>
using namespace std;
class BaseClass1
{public:
    int a, b;
    BaseClass1() { a = 0; b = 0; }
    void BaseFunc11() {}
    void BaseFunc21() {}
};
class DerivedClass1 : public BaseClass1
{public:
    int c;
    DerivedClass1() : BaseClass1(){ c = 0;}
    void DerivedFunc11(){}
};
//I want to confirm that
//1) OBJECT of DerivedClass has it's own member variables a, b c.
//2) OBJECT of DerivedClass has it's own BaseFunc21(), BaseFunc12()
//     and DerivedFunc11().class BaseClass2
{public:
    int a, b;
    BaseClass2() { a = 0; b = 0; }
    BaseClass2(int A, int B) { a = A, b = B; }
    void BaseFunc21() {}
    void BaseFunc22() {}
};
class DerivedClass2 : public BaseClass2
{public:
    DerivedClass2() : BaseClass2(a, b) { }
    DerivedClass2(int b, int c) : BaseClass2(a, b) { }//How many b do we have?
    void DerivedFunc21(){}
};
//Object of DerivedClass2 has member variable a, b and c
//Object of DerivedClass2 has member function BaseFunc21,
//BaseFunc22 and DerivedFunc21.
//b is being declared in DerivedClass2(int b, int c) AND BaseClass2(a, b)
//What does this mean? how many member variable b the DerivedClass2 object has?

int main()
{
    DerivedClass1 DC1;
    DerivedClass2 DC2;
}
From the first comment block above:
//1) OBJECT of DerivedClass has it's own member variables a, b c.
If you mean DerivedClass1, no.
DerivedClass1 has access to the variables a and b of BaseClass1, but it has its own variable c.
//2) OBJECT of DerivedClass has it's own BaseFunc21(), BaseFunc12() and DerivedFunc11().
Again, if you mean DerivedClass1, no for its own copies of BaseFunc11() and BaseFunc12(), and that would be silly and very inefficient if there were multiple copies of these functions. DerivedClass1 has access to these functions. Of course, DerivedFunc11() belongs to DerivedClass1.
yungman said:
2) The second question is more confusing to me as shown with BaseClass2 and DerivedClass2:
Line 33 shows DerivedClass2(int b, int c) : BaseClass2(a, b) { }. Notice variable b is common name defined in DerivedClass2 and in BaseClass2. How many b do I have in the object of derived class? b belongs to DerivedClass2 or BaseClass2?
Your DerivedClass2() constructor is pretty silly. BaseClass2 has two member variables, a and b. DerivedClass2 has no variables of its own, but it has access to the a and b variables that belong to the base class. The fact that you have parameters named b and c for one of the DerivedClass2 constructors doesn't mean anything at all. You could have named them x and y and it would make no difference. You could have done something more interesting if DerivedClass2 had its own variable named a.

Here's an example that's based on yours, but with a lot of cruft removed. Since you didn't do anything with the various member functions, I have omitted them.

Use the debugger to investigate the member variables a and b of BaseClass, and the member variable of DerivedClass2.
C++:
#include<iostream>
using namespace std;
class BaseClass
{
public:
    int a, b;
    BaseClass(int A=0, int B=0) : a(A), b(B) { }    
    
};
class DerivedClass1 : public BaseClass
{
public:
    int c;
    DerivedClass1(int A=0, int B=0, int C=0) : BaseClass(A, B), c(C) { }
};class DerivedClass2 : public BaseClass
{
public:
    int a;
    DerivedClass2(int A = 0, int B = 0) : BaseClass(A, B) 
    {
        a = 5;
    }    
};

int main()
{
    BaseClass BC1(1, 1);
    DerivedClass1 DC1(2, 3, 4);
    DerivedClass2 DC2(2, 3);
}
yungman said:
For default constructor, it's easy to understand. Line 13 DerivedClass1() : BaseClass1(){ c = 0;} just simply combine both constructors to give a=0, b=0 and c=0. But for constructor with arguments and variable with the same name, it get's confusing. which one should I choose.
You have made it more confusing with the different constructor parameter names. Focus on the example I gave above, and maybe it will answer your questions.
yungman said:
For member function with the same name, you can declare virtual in the base member function and the program will know if it's the derived class calls the function, it will just go to the function of the derived class.
Let's work on plain old inheritance before weighing in on virtual functions again.
 
  • #4
Mark44 said:
From the first comment block above:
//1) OBJECT of DerivedClass has it's own member variables a, b c.
If you mean DerivedClass1, no.
DerivedClass1 has access to the variables a and b of BaseClass1, but it has its own variable c.
//2) OBJECT of DerivedClass has it's own BaseFunc21(), BaseFunc12() and DerivedFunc11().
Again, if you mean DerivedClass1, no for its own copies of BaseFunc11() and BaseFunc12(), and that would be silly and very inefficient if there were multiple copies of these functions. DerivedClass1 has access to these functions. Of course, DerivedFunc11() belongs to DerivedClass1.

.....

Thanks Mark for answering, I still need to read the rest, I just want to answer the first part.

I meant the Object of the DerivedClass1, NOT the DerivedClass1. I understand the DerivedClass1 can only access to the BaseClass1. The Object that DerivedClass1 created have ALL the members from both the DerivedClass1 AND BaseClass1.

I have the second program in post 2 to verify all 6 c-strings in the 3 objects (trouble, morTrouble, bigTrouble) from different classes with the same name str and message have different addresses in the memory.
C++:
    Trouble trouble(" Theres trouble");//11,
    MoreTrouble moreTrouble(" More    trouble"); //18,
    BigTrouble bigTrouble(" Real big trouble");//24,
    cout << trouble.message<<",\t&trouble.message = "<<
        &trouble.message<<"\n";//&trouble.message = 0x00609B48
    cout << moreTrouble.message<<",\t&moreTrouble.message = "<<
        &moreTrouble.message<<"\n";//&moreTrouble = 0x0053F834
    cout << bigTrouble.message <<",\t&bigTrouble.message = "<<
        &bigTrouble.message<<"\n\n";//&bigTrouble.message = 0x0053F7F8

I want to verify I am right, this is very important. I'll look at the other part of your comment in a little bit.

Thanks so much.
 
Last edited:
  • #5
Hi Mark, I am going to work on your sample program tomorrow, I am still on the first part of my question so far.

I whipped up a very simple program to proof my point that the OBJECT of the derived class contains of all the members of both the Base class and Derived class.
C++:
//Base/derived class member components
#include <iostream>
using namespace std;
class Base
{
public:
    int a;
    Base() { a = 0; }
    void setA(int A) { a = A; }
    int getA() { return a; }
};
class Derived : public Base
{
public:
    int b;
    Derived() : Base() { b = 0; }
    void setB(int B) { b = B; }
    int getB() { return b; }
};
int main()
{
    Base Be;
    Be.setA(5);
    Derived Dev1, Dev2;
    Dev1.setA(10);
    Dev2.setA(-10);
    Dev1.setB(20);
    Dev2.setB(-20);
// Line below shows the value and address of variable a in the object of Base class
    cout << " Be.getA()  = " << Be.getA()   << ",\t&Be.a   = " << &Be.a << "\n\n";

//below shows the the values of a and b of the two Objects of derived class are unique
    cout << " Dev1.getA()= " << Dev1.getA() << ",\t&Dev1.a = " << &Dev1.a << "\n";
    cout << " Dev2.getA()= " << Dev2.getA() << ",\t&Dev2.a = " << &Dev2.a << "\n\n";

    cout << " Dev1.getB()= " << Dev1.getB() << ",\t&Dev1.b = " << &Dev1.b << "\n";
    cout << " Dev2.getB()= " << Dev2.getB() << ",\t&Dev2.b = " << &Dev2.b << "\n\n";
}
The output of program is shown below:
Object values and address.jpg


I have one Object Be of the Base class, I have two Objects Dev1 and Dev2 of the Derived class. I set the values of a and b for Objects Be, Dev1 and Dev2. The program read the values of a and b for all three objects together with the ADDRESS of a and b of EACH Object. You can see all the addresses are unique. this show each Object of the derived class has all the members from the Derived class AND Base class.

ThanksEDIT: I just downloaded your sample program and look at it. It is so similar to the program I put together above. I swear I did not look at your program to write mine. I just need to add the cout statement to your program. That shows great mines think alike! :)

Good night, I am going to work on it tomorrow.
 
Last edited:
  • #6
yungman said:
I meant the Object of the DerivedClass1, NOT the DerivedClass1. I understand the DerivedClass1 can only access to the BaseClass1. The Object that DerivedClass1 created have ALL the members from both the DerivedClass1 AND BaseClass1.
Yes, I was talking about objects of DerivedClass1. When you get a chance to look at my example in post #3, things should be a little clearer. A derived class contains a base class instance that has the data members of the base class, plus any data members it happens to declare. Both classes have tables of links to their functions; i.e., pointers to functions. As I recall these are called v-tables.

Another example:
C++:
#include<iostream>
using std::cout;
using std::endl;        // I don't write "using namespace std;" if I don't need it.

class BaseClass
{
public:
    int a, b;
    BaseClass(int A=0, int B=0) : a(A), b(B) { }
    void fun() { cout << "Hi from base class!" << endl; }   
};

class DerivedClass1 : public BaseClass
{
public:
    int c;
    DerivedClass1(int A=0, int B=0, int C=0) : BaseClass(A, B), c(C) { }
};

class DerivedClass2 : public BaseClass
{
public:
    int a;
    DerivedClass2(int A = 0, int B = 0) : BaseClass(A, B)
    {
        a = 5;
    }   
    void fun()
    {
        cout << "Hi from DerivedClass2!" << endl;
        BaseClass::fun();            // Call fun() in base class
    }
};

int main()
{
    BaseClass BC1(1, 1);
    BC1.fun();
    DerivedClass1 DC1(2, 3, 4);
    DC1.fun();
    DerivedClass2 DC2(2, 3);
    DC2.fun();
}
 
  • #7
Mark44 said:
Yes, I was talking about objects of DerivedClass1. When you get a chance to look at my example in post #3, things should be a little clearer. A derived class contains a base class instance that has the data members of the base class, plus any data members it happens to declare. Both classes have tables of links to their functions; i.e., pointers to functions. As I recall these are called v-tables.
The highlighted portion applies only to virtual functions. Objects don't need a table of pointers to their non-virtual functions (either their own or the ones in any base classes) because the appropriate function to call is known at compile time. The compiler generates these calls directly, not via a v-table.
 
  • #8
@jbunniii, that thought occurred to me -- that the v-table really was a table of links to virtual functions. It's been many years since I thought about them.
 
  • #9
Hi Mark, I am still working hard on your program, It is NOT what I expected. Let me stew on it a little more. I'll be back.

Thanks
 
  • #10
Hi Mark

OK, I read through the program, added lines to display values and address of a, b and c inside the BaseClass, and the two DerivedClass. Also Display the values and address for BC1, DC1 and DC2.

In my program, look at every line, I have the stepping to the next line in comment at the end of each line like: //go to line #. So you can step through the program just by following the numbers, don't have to step in Debug.

C++:
#include<iostream>
using namespace std;
class BaseClass
{public:    int a, b;
    BaseClass(int A = 0, int B = 0)                                 // 6
    { a = A; b = B;                                                 // 7
      cout<<" In BaseClass constructor, a = "<<a<<", b = "
       <<b<< ",\t&a = " << &a <<", &b = " << &b << "\n";            // 9
    }                                                       //29, 14, 22
};
class DerivedClass1 : public BaseClass
{public:    int c;
    DerivedClass1(int A = 0,int B = 0,int C = 0):BaseClass(A,B)     // 5
    {   c = C;                                                  //13, 15
        cout << " In DerivedClass1, a=" << a << ", b= "<<b<<", c="  //
      <<c<<",\t\t&a = "<<&a<<", &b = "<<&b <<", &c = "<<&c<<"\n\n"; //17
    }                                                               //31
};
class DerivedClass2 : public BaseClass
{public:    int a;
    DerivedClass2(int A = 0, int B = 0) : BaseClass(A, B)           // 5
    {   a = 5;                                                  //21, 23
        cout << " In DerivedClass2,\ta =" << a << ", b="<<b<<
          ",\t\t&a = " << &a << ", &b = " << &b << "\n\n";          //25
    }                                                               //33
};
int main()
{   BaseClass BC1(1, 1);                                            //5
    cout << "\n Creating DC1:\n";                                   //30
    DerivedClass1 DC1(2, 3, 4);                                     //14
    cout << "\n Creating DC2:\n";                                   //32
    DerivedClass2 DC2(2, 3);                                        //22
    cout<<" BC1(a,b) \t= ("<<BC1.a<<", "<<BC1.b<<
    ")\t  &BC1.a and b:\t     "<<&BC1.a<<",      "<<&BC1.b<<"\n\n"; //36
                                                                 
    cout<<" DC1(a,b,C)\t= ("<<DC1.a<<","<<DC1.b<<","<<DC1.c<<    
        ")\t  &DC1.a, b and c:   "<<&DC1.a<<",\t    "<<&DC1.b<<  
        ",\t   "<< &DC1.c<<"\n\n";                                  //40
                                                                 
    cout<<" DC2(a,b)\t= ("<<DC2.a<<", "<<DC2.b<<","<<            
     ")\t  &DC2.a and b :     "<<&DC2.a<<",\t    "<<&DC2.b<<"\n\n"; //42
}

This is the screen capture of the output of the program in cmd:
Marks result.jpg

This is my observation and reasoning:

For DerivedClass1, a and b are NOT defined in DerivedClass1, so it just take the a and b from the BaseClass. c is defined in DerivedClass1, no issue there.

In DerivedClass2, only a is defined, Pay attention to DC2, the address and the value of a in BaseClass constructor and DerivedClass2 is different both the value and address. Seems like when a is redefined in DerivedClass2 , it takes precedence over the variable a in the BaseClass. Is this correct?

Seems like Both DC1 and DC2 objects contain ALL the variables defined in Base and Derived classes like I said, just the matter of who takes precedence when BOTH declare variables of SAME name.

What am I missing?

Thanks
 
Last edited:
  • #11
OK, I want to proof my point that if both Baseclass and DerivedClass declare a variable of the SAME NAME, the one in DerivedClass takes precedence. I modified the program by forcing a = -10 and b = -20 in line 6 of the BaseClass and here are the results:
C++:
#include<iostream>
using namespace std;
class BaseClass
{public:    int a, b;
    BaseClass(int A = 0, int B = 0)                                 // 6
    { a = -10; b = -20;                                             // 7
      cout<<" In BaseClass constructor, a = "<<a<<", b = "
       <<b<< ",\t&a = " << &a <<", &b = " << &b << "\n";            // 9
    }                                                       //29, 14, 22
};
class DerivedClass1 : public BaseClass
{public:    int c;
    DerivedClass1(int A = 0,int B = 0,int C = 0):BaseClass(A,B)     // 5
    {   c = C;                                                  //13, 15
        cout << " In DerivedClass1, a=" << a << ", b= "<<b<<", c="  //
      <<c<<",\t\t&a = "<<&a<<", &b = "<<&b <<", &c = "<<&c<<"\n\n"; //17
    }                                                               //31
};
class DerivedClass2 : public BaseClass
{public:    int a;
    DerivedClass2(int A = 0, int B = 0) : BaseClass(A, B)           // 5
    {   a = 5;                                                  //21, 23
        cout << " In DerivedClass2,\ta =" << a << ", b="<<b<<
          ",\t\t&a = " << &a << ", &b = " << &b << "\n\n";          //25
    }                                                               //33
};
int main()
{   BaseClass BC1(1, 1);                                            //5
    cout <<"\n Create DC1, only c is declared in DerivedClass1:\n"; //30
    DerivedClass1 DC1(2, 3, 4);                                     //14
    cout << "\n Create DC2, only a is declared in DerivedClass1\n"; //32
    DerivedClass2 DC2(2, 3);                                        //22
    cout<<" BC1(a,b) \t= ("<<BC1.a<<", "<<BC1.b<<
    ")\t  &BC1.a and b:\t     "<<&BC1.a<<",      "<<&BC1.b<<"\n\n"; //36
                                                                 
    cout<<" DC1(a,b,C)\t= ("<<DC1.a<<","<<DC1.b<<","<<DC1.c<<    
        ")\t  &DC1.a, b and c:   "<<&DC1.a<<",\t    "<<&DC1.b<<  
        ",\t   "<< &DC1.c<<"\n\n";                                  //40
                                                                 
    cout<<" DC2(a,b)\t= ("<<DC2.a<<", "<<DC2.b<<","<<            
     ")\t  &DC2.a and b :     "<<&DC2.a<<",\t    "<<&DC2.b<<"\n\n"; //42
}

This is the screen shot of the cmd window:
Marks result1.jpg
After I played with your program for like 10 hours, I still see the OBJECT of the DerivedClass contain ALL the variables from BOTH the BaseClass and the DerivedClass.
And from this program, If a variable is declared with the SAME in both BaseClass and Derived Class, the one in the DerivedClass takes precedence as shown that in the Object DC2 of DerivedClass2 that the value remains as (5, -20).
 
Last edited:
  • #12
yungman said:
In DerivedClass2, only a is defined, Pay attention to DC2, the address and the value of a in BaseClass constructor and DerivedClass2 is different both the value and address. Seems like when a is redefined in DerivedClass2 , it takes precedence over the variable a in the BaseClass. Is this correct?
a is defined in DerivedClass2, but a is also defined in BaseClass. The data member a in DerivedClass2 is not redefining the one with the same name in BaseClass - it overrides the base class member of the same name. They are both there in the derived class.

Here's a slight refinement of the DerivedClass2 class declaration:
C++:
class DerivedClass2 : public BaseClass
{
public:
    int a;
    DerivedClass2(int A = 0, int B = 0) : BaseClass(A, B) 
    {
        a = 5;
    }    
    void fun() 
    { 
        cout << "Hi from DerivedClass2!" << endl;
        cout << "DerivedClass2.a: " << a << endl;
        BaseClass::fun();            // Call fun() in base class
        cout << "BaseClass.a: " << BaseClass::a << endl;
    }
};
When fun() is called, such as from main(), the code above will display the values of both a members. Without being qualified, a evaluates to the DerivedClass2 member. By being qualified, as in BaseClass::a evaluates to the BaseClass member.

If you replace the DerivedClass2 declaration in my earlier example with the code above, you'll see both a members are present.
yungman said:
Seems like Both DC1 and DC2 objects contain ALL the variables defined in Base and Derived classes like I said, just the matter of who takes precedence when BOTH declare variables of SAME name.
What am I missing?
Like I said, the a in DerivedClass2 overrides a in BaseClass, but it's possible to access both of them.
yungman said:
After I played with your program for like 10 hours, I still see the OBJECT of the DerivedClass contain ALL the variables from BOTH the BaseClass and the DerivedClass.
Well, yes.
yungman said:
And from this program, If a variable is declared with the SAME in both BaseClass and Derived Class, the one in the DerivedClass takes precedence as shown that in the Object DC2 of DerivedClass2 that the value remains as (5, -20).
The derived class data member overrides the data member of the same name in the base class. Also, (5, -20) is not a value. It's a pair of numbers, the values of a and b.
 
  • Like
Likes yungman
  • #13
Thanks Mark for all your help, I really learn a lot. BUT, I am on strike right now. I spent like 10 hours on your program, I can't do it anymore tonight. I still yet to get to your second program and this one! You are a good teacher.

BTW, you really should write a book. I own like 6 books on C++, other than Gaddis ( which he kind of fizzled out after chapter 13) that explain in simple ways and simple example programs, ALL the others that I went through so far are really not that good, their working programs are really not very good. The I read a little of the C++ Primer by Lippman, the writing at least is quite good so far, but it has no program so far, just snipped of codes, I can't depend on it to learn because working on the program is a huge part of learning.

You should consider writing a book, your programs are good. I spent 10 hours on your program, it gave me a platform to add all the cout, change stuffs to verify which variable doing what. I learn so much today than all the books I read and work on.

Maybe be I am the only person that find C++ books and reading on line hard, if I did not study all my life in much more difficult subjects, I would just blame on my reading comprehension. But all the books that I studied, most I don't have problem reading what they try to say, it's more like understanding what they are teaching if you know what I mean. In another words, the description are very clear, it's the materials are just hard to understand. Gaddis is the only one that can explain things in a simple way so far, but he really dropped the ball towards the end.

Being good in a field and being able to convey what the person knows are two completely different matter. A lot of people that are good in programming cannot convey to other people. This is how I feel when I studied all the other books on C++. To write a book, one has to be able to put themselves to the student's level, not like talking to peers.

I think you can do it, I don't know why all the other books are like this, but my experience from learning from you and look at your examples, I really think you should seriously consider writing a book on C++. People will thank you for this.

Alan
 
  • Like
Likes Filip Larsen
  • #14
Hi Mark
I can't help it, have to work on your second program. Upon reading through, there is a lot of redundancy from the first program that I spent a lot of time. So I decided to get rid of all the common lines of a, b and c. I simplified further just to show Object DC2 has a member function fun() that is inherited from the BaseClass.

C++:
#include<iostream>
using std::cout;
using std::endl;   
class BaseClass
{public:
    void fun() { cout << " BaseClass!" << endl; }//17
};
class DerivedClass : public BaseClass
{public:
    void fun2()
    {   cout << " DerivedClass!" << endl;   }//16
};
int main()
{   DerivedClass DC2;//15
    DC2.fun2(); //11
    DC2.fun();//6 This shows fun() is member function of DerivedClass by inheritance.
}

I think I understand quite well now.

1) Object of DerivedClass has all the member variables and function from the DerivedClass AND the BaseClass.

2) If the member in DerivedClass has the same name of the member in the BaseClass, The member in DerivedClass OVERRIDES the member in the BaseClass.

Thanks so much
 
  • #15
As I skimmed this post I wondered why the OP isn't using the "initializer list" to initialize members:

https://en.cppreference.com/w/cpp/language/constructor

Ech, it's probably not relevant (maybe for delegating c-tors but surely not for performance reasons). Sorry for mixing in.

Regards.

EDIT:

Yeah, it's pretty academic although:

https://www.webwise-scripts.com/c++faq/init-lists.html

Sorry, got carried away a little...

EDIT2: Heh, and getting carried away by a discussion on c++ and initialiazer lists on a saturday evening is actually a little sad. :)
 
Last edited:
  • #16
yungman said:
The I read a little of the C++ Primer by Lippman, the writing at least is quite good so far, but it has no program so far, just snipped of codes, I can't depend on it to learn because working on the program is a huge part of learning.
I have an older book by Stanley Lippman, C++ Primer, 2nd Ed. (1992). Lippman was a major player in the development of C++, working with Bjarne Stroustrup at AT&T Bell Labs. In the book I have, Lippman doesn't present a whole program in one shot -- he breaks it down into parts that he discusses separately. You can't take a snippet in the middle of a section and build a program, but you should be able to look at the preceding material in that section to see how things fit together.
yungman said:
You should consider writing a book, your programs are good. I spent 10 hours on your program, it gave me a platform to add all the cout, change stuffs to verify which variable doing what.
I was involved in writing one years ago, but my efforts were mostly about making some significant revisions and corrections to a something that that had been published previously. I have no interest in writing a book again.
In the programming classes I teach, I usually work from a textbook, but I always try to come up with my own examples, and don't just present the same ones that are in the book. I also try to make the examples more interesting and more relevant to my students.

BTW, I don't understand why you add all the output statements. In the old days, about 40+ years ago, the main debugging technique was output statements, since there were no debuggers. But now, with very capable debuggers, you can see the values of variables while you step through a program. IMO, adding a lot of output statements detracts from the code, cluttering it up and making it harder to read than it needs to be.

There are some kinds of programs where output statements are necessary, such as debugging client/server code where you don't even know which computer the server software is running on. This was an experience I had while I was testing some Sharepoint code I wrote about 7 years back.
 
  • Like
Likes jbunniii and yungman
  • #17
Mark44 said:
I have an older book by Stanley Lippman, C++ Primer, 2nd Ed. (1992). Lippman was a major player in the development of C++, working with Bjarne Stroustrup at AT&T Bell Labs. In the book I have, Lippman doesn't present a whole program in one shot -- he breaks it down into parts that he discusses separately. You can't take a snippet in the middle of a section and build a program, but you should be able to look at the preceding material in that section to see how things fit together.
I was involved in writing one years ago, but my efforts were mostly about making some significant revisions and corrections to a something that that had been published previously. I have no interest in writing a book again.
In the programming classes I teach, I usually work from a textbook, but I always try to come up with my own examples, and don't just present the same ones that are in the book. I also try to make the examples more interesting and more relevant to my students.

BTW, I don't understand why you add all the output statements. In the old days, about 40+ years ago, the main debugging technique was output statements, since there were no debuggers. But now, with very capable debuggers, you can see the values of variables while you step through a program. IMO, adding a lot of output statements detracts from the code, cluttering it up and making it harder to read than it needs to be.

There are some kinds of programs where output statements are necessary, such as debugging client/server code where you don't even know which computer the server software is running on. This was an experience I had while I was testing some Sharepoint code I wrote about 7 years back.
Being the pioneer in the field and knowing how to explain the common people, the students that trying to learn is a TOTALLY different thing. I worked with a lot of PhDs in my career, One person named Bruno, he is the chief scientist that developed all the semi-conductor testing equipment( very much like mass spectrometers, electron microscope or small version of the Stanford Linear Accerlarator etc.) all these years. During the meetings, it's so hard to understand what he said, he literally jump words. He thinks he explain, he really doesn't.

40 years ago, the the top textbook on semi-conductor design was by Grey & Meyer. Gray was a professor in UC Berkley, I did not think the book was easy to understand. The company I worked for Exar Corp used to play his lectures at lunch time. It was SO BORING, I sat there a lot...Not to listen to him, but to snooze! He has a voice that make you fall asleep!

I always email to college professors what book they use in the subject and I buy those textbooks. They all seems to find books that are easier to understand by STUDENTS. Like PDE book by Asmar, EM book by Cheng etc. They are all very good book for students. Remember, you don't write books for peers, you write book to teach people that don't know the subject. I got the Gaddis from my grandson's school, it is good for the subject that covered in his class for sure.

I was complaining ( still kind of) it's hard to understand all the on line site on C++, you all accused me why I didn't go on line to search before asking questions. I did, I didn't understand them! It got easier 3 months into my study that I know a lot more than at the beginning. I feel they explain to people that already understand the topics, not for students that just starting out, all the names, the terms. You and people here might think it's very clear, you guys are the PEERS, not the students. Why write a book for peers? That's what I don't see in C++.

It is a lot more forgiving to write for more difficult subjects like EM and RF. The subject is very very hard. By default, you have to read the chapter over and over. So it's a lot more forgiving for bad presentation as you have to read, chew on it, read it over, chew on it again. If you can cover a few pages a day, you are doing great already.

In C++ programming, there is so so many little function, different ways to do things, options, short cuts and all that. Every chapter is full of those. None of them by itself is hard to understand at all. BUT there's just so so many of them. Just take for example the overloading operators, one chapter have all different operators, then each have their own requirements like how to write it, what arguments needed and all that. The last thing is to have confusing writing on top that you have to read over and over to try to understand. Electromagnetics have ONLY 4 main formula, you have a whole book to explain the 4 formula, so it's a lot more forgiving in how you write the book! You have so so many little thing in C++, I cannot afford to chew on every one of them!

It's a gift if you can convey your knowledge to student, not just to peers.

Just a point of view of one student.
 
  • #18
The post was too long, so I respond about putting all the output statements.

Remember I am old, cognitively declined. If I just stepping through debug, it's so clear at the time. Then I forgot a few days later! With this, I can read back. More importantly, I can print the result out, line by line compare and see why it happened that way. I got that from Jtbell, I have been using it since. I even put a lot of these in my notes.
 
  • #19
yungman said:
It is a lot more forgiving to write for more difficult subjects like EM and RF. The subject is very very hard. By default, you have to read the chapter over and over.
yungman said:
In C++ programming, there is so so many little function, different ways to do things, options, short cuts and all that. Every chapter is full of those. None of them by itself is hard to understand at all. BUT there's just so so many of them.
So are you saying that C++ is not difficult, and that you don't have to read the chapters over and over? I don't think anyone ever claimed C++ was easy to learn, especially the object-oriented parts. You spent the first few months on the easy parts of C++, the parts where you could build on what you had done years before. After that, you got into completely new territory, with pointers, classes, inheritance, polymorphism, and so on. Many of the problems you have run into seem to me to be an incomplete understanding of the latter topics coupled with the fact that the textbooks are in English, which isn't your native language. At least in EM, there are lots of formulas, which are a universal language.
yungman said:
Remember I am old, cognitively declined. If I just stepping through debug, it's so clear at the time. Then I forgot a few days later! With this, I can read back.
This is where useful comments really shine. Instead of useless comments like the one below --
C++:
int x = 5;   // integer x is declared and initialized to 5
-- a useful comment at the top of a function or class or block of code can summarize things that you discovered that weren't completely obvious.
 
  • #20
Difficult is relative. Difficult in C++ is it just has a lot of small individual stuffs to learn, individual one is not difficult. ODE was difficult to me. That was the only class I actually took in the last 30+years. I was told PDE was the hardest, I breezed through multi-variable, thinking I can be lazy and took a class so I didn't have to study. WRONG, that was killing me. I was the first in the class, but you don't know how much time I put in even with the professor's help. Then when going to PDE, it was hard, but nothing like ODE to me. EM is hard. When I said reading over and over, I mean over 10 times. I started out with an easier book used in San Jose State by Uleby, then go onto Cheng with other supplement books like Klaus. The whole journey is over 3 years. Yes, I would say that is hard. All EE supposed to study these, but ask any EE, they run away from this, barely get by and put it all behind. Most of them run away from RF and microwave.

I am not like before anymore, easier to get confused, forgetful now. I don't think I stand a chance to study another subject like those before now. Actually I dropped half way studying antenna in 2012 because I was already too forgetful, I could write good notes, but few weeks later, I read back my notes, I had no idea I wrote that. Then I studied my notes, it's all there, I did really understand it. I finally quit half way, just not meant to be anymore. Yes, I studied AFTER I retired. I had my full career in EE without studying all the stuffs, I just did not feel good. So even after I retired, I studied back everything to beyond undergrad, just because I want to.

Believe me, you think I am confused, actually I forgot! So many times I asked the question I thought I never saw before, then read back my notes and found it's there. Believe me, You are expert in C++, you don't forget just like me facing electronic problems, it's like part of me and I don't get confused. Try study a new subject you are not good at. I don't know whether you know electronics or not. If not, try study a few chapters and you'll see.
 
  • #21
yungman said:
C++ is it just has a lot of small individual stuffs to learn, individual one is not difficult

I think you are underestimating the difficulty, Mark mentioned pointers. As recently as Tuesday you were using pointers incorrectly. Further, your attempted solution was to add a "*" and see if it helped. I think you would be a lot happier later if you reviewed pointers now.

yungman said:
So many times I asked the question I thought I never saw before, then read back my notes and found it's there

It might be a good idea then to review your notes as soon as you have a question.
 
  • #22
Vanadium 50 said:
I think you are underestimating the difficulty, Mark mentioned pointers. As recently as Tuesday you were using pointers incorrectly. Further, your attempted solution was to add a "*" and see if it helped. I think you would be a lot happier later if you reviewed pointers now.
It might be a good idea then to review your notes as soon as you have a question.
I never said it's easy, if it is easy, I would not have pick this up as exercise for my old brain. Why do you think I pick up C++ out in the blue? Not only programming, I had to pick the most difficult one to study? It's not easy to find something challenge enough to worth the time. I have been looking for a while before I landed on C++.

I would say it's is at the level of hardware engineering designing micro-processor mother board, memory module before it became so fast that it's behave like RF. It is NOT easy by any means.

I don't mean to be insulting or put down, I was actually complementing Mark that he can explain in very simple way and his examples are really good. That's I don't see other books except Gaddis are good so far. That he should write a C++ book. I was just comparing other books with the C++ book I read.

You did not read my reply to you last time. I said I try everything logical, then the next logical step is to try illogical ways! Yes, I never know about c-string has no type, that you CANNOT return c-string as it needs a type to return...This thanks to you explain this, now I know.

You want to talk about crazy? I have been into Electronics all my life. do you know what I would do first when anything like tv, computer, printer...all the electronics stuff fails? First and foremost is...give it a slap with my hand. If it is too heavy to make a difference, lift it up 1" or 2"...DROP it down. Then we'll see what happens! Yes, you'd be surprise how much this can tell you! You can't imagine how much problem a loose connector or cold solder on pcb happens on stuffs that've been working for 10+ years...
 
  • #23
sbrothy said:
As I skimmed this post I wondered why the OP isn't using the "initializer list" to initialize members:

https://en.cppreference.com/w/cpp/language/constructor

Ech, it's probably not relevant (maybe for delegating c-tors but surely not for performance reasons). Sorry for mixing in.

Regards.

EDIT:

Yeah, it's pretty academic although:
It's not academic. Some types of members (notably references and const members) can only be initialized via the initializer list.
 
  • #24
yungman said:
Why write a book for peers? That's what I don't see in C++.
If by "peers" you mean experienced programmers, there's certainly a market for such books. Many people who are learning C++ already know how to program in several other languages with similar features (such as Java) so they don't need a primer on object-oriented programming or full examples of working programs. Instead they need to focus on stuff that is specific/unique to C++. An example of a book aimed at this audience is Stroustrup's The C++ Programming Language.

A reasonable question would be: do we need any more books of this type, given that Stroustrup's exists? The answer would probably be no if he would keep it updated, but the latest edition is nearly ten years old and only covers up to C++11. And as far as I know, he isn't planning to update it, and that means there's currently a vacuum for those who already know C++17 but want a book covering the major, huge new features of C++20.
 
  • #25
jbunniii said:
If by "peers" you mean experienced programmers, there's certainly a market for such books. Many people who are learning C++ already know how to program in several other languages with similar features (such as Java) so they don't need a primer on object-oriented programming or full examples of working programs. Instead they need to focus on stuff that is specific/unique to C++. An example of a book aimed at this audience is Stroustrup's The C++ Programming Language.

A reasonable question would be: do we need any more books of this type, given that Stroustrup's exists? The answer would probably be no if he would keep it updated, but the latest edition is nearly ten years old and only covers up to C++11. And as far as I know, he isn't planning to update it, and that means there's currently a vacuum for those who already know C++17 but want a book covering the major, huge new features of C++20.
Hi Jbunniii

From my limited experience, there are a lot of books that seems to be for peers, sure it's not for student like me. thanks for suggesting the C++ Primer, the content is better than the rest except Gaddis.

In the marketing point of view, you earn a whole lot more money if your book is used by colleges. Look at Gaddis, it's obvious it's been selling like hot cakes, all the used one on the market which means people ( students) finished their semester and selling the book. When I finish learning C++ and only want up date in the future, I am sure I can find the material on line as there are plenty of sites like cplusplus and all that which will give you the information on the updates. Like I said before, the main issue for me( I am pretty sure I can speak for student just starting out) is to understand what the web sites talking about. I had a hell of a time understanding what they are trying to say. The Gaddis sure saved the day for me.

From my collection, there are sure a lot more difficult books than a simple book like Gaddis. For anyone that want to start learning C++, I have no reservation to advice them to buy the Gaddis book over ANY other ones even though it fizzles out after Chapter 13.

From my experience ( I am one of these), there are a lot of people that go into the field without a formal education, you'd be surprised how many people in a career that is not their major in college. Those people( me included) have to start somewhere from very beginning. A good easy to read book can sure comes in handy. I know, I was in a way very lucky that I asked Heald College( just a trade school) what book they used for their analog electronics class, it was book by Malvino in 1979.
https://www.amazon.com/dp/0070398674/?tag=pfamazon01-20

It's such a good book. I studied 4 months on this book and got my first real job in my life and never looked back.(of cause, I studied digital and microprossor at the time also, but this is really the book that give me my career as I used the stuffs in the book for years). I even got into analog IC design with the knowledge of mostly from this book in 1984. It is a very simple book, easy to understand but it's absolutely useful in real world. Later on when I became the manger of EE, I used similar questions from this book to give test to engineers during the interview, you should see them sweating it out! I lost that book long time ago, I even attempted to buy a newer edition just for keep sake, but I bought the solution book by accident and never attempt to buy one again. Malvino must be making boat load of money on this book.( Well relatively, you don't get rich writing books).
 
  • #26
I have a strange error I cannot explain. This is really simple, but that's what make it hard!
C++:
#include<iostream>
using std::cout;
class Bclass  //members = a, b, fun0 and fun1
   {public: int a = 2, b = 3;
    void fun0() { cout << " Bclass fun0()." << "\n\n";}
    void fun1() { cout << " Bclass fun1()." << "\n\n";}};
class Dclass : public Bclass//members = a, fun1 and fun2
{public: int a = 5;//This overrides a in Bclass.
    cout << " Dclass.a = " << a << ", Bclass.a = " << Bclass.a << "\n\n";
    void fun1() { Bclass::fun1(); }//use fun1 in Bclass
    void fun2() { cout << " Dclass fun2()." << "\n\n";} };
int main() 
   {Dclass DC2; DC2.fun0(); DC2.fun1(); DC2.fun2();
    cout << " DC2.a= " << DC2.a << ", DC2.b= " << DC2.b << "\n\n";
}//a in Dclass overrides a in Bclass, DC2.a=5. b inherits from Bclass.
This is the error:
Error.jpg

I have no idea why this won't work. Just a simple cout statement!

Strange!

Thanks
 
  • #27
yungman said:
I have a strange error I cannot explain. This is really simple, but that's what make it hard!
C++:
#include<iostream>
using std::cout;
class Bclass  //members = a, b, fun0 and fun1
   {public: int a = 2, b = 3;
    void fun0() { cout << " Bclass fun0()." << "\n\n";}
    void fun1() { cout << " Bclass fun1()." << "\n\n";}};
class Dclass : public Bclass//members = a, fun1 and fun2
{public: int a = 5;//This overrides a in Bclass.
    cout << " Dclass.a = " << a << ", Bclass.a = " << Bclass.a << "\n\n";
    void fun1() { Bclass::fun1(); }//use fun1 in Bclass
    void fun2() { cout << " Dclass fun2()." << "\n\n";} };
int main()
   {Dclass DC2; DC2.fun0(); DC2.fun1(); DC2.fun2();
    cout << " DC2.a= " << DC2.a << ", DC2.b= " << DC2.b << "\n\n";
}//a in Dclass overrides a in Bclass, DC2.a=5. b inherits from Bclass.
This is the error:
View attachment 277224
I have no idea why this won't work. Just a simple cout statement!
Your attempt to call cout is not inside any function definition. This is not allowed. Did you mean to do it inside the Dclass constructor? If so, you have to define a Dclass constructor!
 
  • Like
Likes yungman and Vanadium 50
  • #28
yungman said:
I have no idea why this won't work.

C++:
main() {
}
cout << "See why this won't work?" << endl;
 
  • Like
Likes yungman
  • #29
Vanadium 50 said:
C++:
main() {
}
cout << "See why this won't work?" << endl;
But the line is inside the {} of class Dclass {...}

I just don't see it! I must be missing big time here!

thanks
 
  • #30
But it's not in a function.

Think about it this way - when do you expect it to run?
 
  • Like
Likes yungman
  • #31
Vanadium 50 said:
But it's not in a function.

Think about it this way - when do you expect it to run?
Ah! I have to try to execute the line, the line is just sitting there!

I'll be back. Thanks so much.
 
  • #32
Thank you, it works. Never thought of this! That the line needs to be called, too used to just cout in main().

Thanks
 
  • #33
yungman said:
I have a strange error I cannot explain.
C++:
#include<iostream>
using std::cout;
class Bclass  //members = a, b, fun0 and fun1
   {public: int a = 2, b = 3;
    void fun0() { cout << " Bclass fun0()." << "\n\n";}
    void fun1() { cout << " Bclass fun1()." << "\n\n";}};
class Dclass : public Bclass//members = a, fun1 and fun2
{public: int a = 5;//This overrides a in Bclass.
    cout << " Dclass.a = " << a << ", Bclass.a = " << Bclass.a << "\n\n";
    void fun1() { Bclass::fun1(); }//use fun1 in Bclass
    void fun2() { cout << " Dclass fun2()." << "\n\n";} };
int main()
   {Dclass DC2; DC2.fun0(); DC2.fun1(); DC2.fun2();
    cout << " DC2.a= " << DC2.a << ", DC2.b= " << DC2.b << "\n\n";
}//a in Dclass overrides a in Bclass, DC2.a=5. b inherits from Bclass.
If you didn't cram all your code so tightly, it might have been more obvious that you have an executable statement (the output line) in amongst the declarations of the Dclass members. It's a false economy to jam everything together like you often seem to do.
 
  • Like
Likes Vanadium 50
  • #34
Mark44 said:
If you didn't cram all your code so tightly, it might have been more obvious that you have an executable statement (the output line) in amongst the declarations of the Dclass members. It's a false economy to jam everything together like you often seem to do.
It's one line of code per line. It's not tight without the comments.
 
  • #35
yungman said:
It's one line of code per line.

That is tautologically true. It also misses the point: most people would write
Code:
void fun1() { cout << " Bclass fun1()." << "\n\n";}};
as either 4 or 5 lines.

Mark told you many times that this is good practice.
You have not done this - even after running into problems doing it "your way". Repeatedly.
Why is that? Do you think you're smarter than Mark? Do you think you're a better programmer? Is it because you know that if you get into trouble we will bail you out again and again and again?
 
  • Like
Likes Mark44

Similar threads

Replies
36
Views
2K
Replies
89
Views
5K
Replies
17
Views
2K
Replies
36
Views
4K
Replies
2
Views
983
Replies
7
Views
2K
Replies
25
Views
2K
Replies
35
Views
3K
Replies
6
Views
1K
Replies
36
Views
2K
Back
Top