Advertisement

Inheiritance

Started by August 23, 2002 12:51 PM
4 comments, last by Zorbfish 22 years, 3 months ago
Ivor Horton cites this example in his section on Inheiritance (Beginning VC++ 6.0)

// Listing 8_01-01
class Box
{
   public:
      double length;
      double breadth;
      double height;
      Box(double lv=1.0, double bv=1.0, double hv=1.0)
      {
         length = lv;
         breadth = bv;
         height = hv;
      }
};

// Listing 8_01-02
class CandyBox: Box
{
   public:
      char* contents;
      CandyBox(char* str= "Candy")            // Constructor
      {
         contents = new char[ strlen(str) + 1 ];
         strcpy(contents, str);
      }

      ~CandyBox()                             // Destructor
      { delete[] contents; };
};
 
I understood the syntax and procedure going on so I wrote some code just to reinforce what I knew. My code:

class CBase{
public:
	CBase(int one,int two,int three);
	~CBase();
// example member variables
int m_one;
int m_two;
int m_three;
};

class CSpecial:CBase{
public:
	CSpecial(int one,int two,int three,int four);
	~CSpecial();
m_four;
private:
	bool hasNumber(int num);
};

CBase::CBase(int one,int two,int three){
int m_one=one;
int m_two=two;
int m_three=three;
	cout << "Object Created" << endl;
};

CBase::~CBase(){
	cout << "Object Deleted" << endl;
};

CSpecial::CSpecial(int one,int two,int three,int four){
int m_one=one;
int m_two=two;
int m_three=three;
int m_four=four;
	cout << "Object Created" << endl;
};

CSpecial::~CSpecial(){
	cout << "Object Deleted" << endl;
};
 
When I compile this I recieve an error saying there is no default constructor for CBase and the error tag points to CSpecial''s constructor. What''s is different from Horton''s example?
The problem is your constructor expects values which are not given by default.

CSpecial(int one,int two,int three,int four);
should change to
CSpecial(int one=1,int two=2,int three=3,int four=4);

or something along those lines.

The alternative is to have a constructor that takes no parameters: CSpecial::CSpecial() {}
and then have your overloaded constructor as you had it.

The point is the compiler has to be able to access a constructor that has some default data, whether it be an empty constructor or one that initializes with some default variables.
Advertisement
The problem is your constructor expects values which are not given by default.

CSpecial(int one,int two,int three,int four);
should change to
CSpecial(int one=1,int two=2,int three=3,int four=4);

or something along those lines.

The alternative is to have a constructor that takes no parameters: CSpecial::CSpecial() {}
and then have your overloaded constructor as you had it.

The point is the compiler has to be able to access a constructor that has some default data, whether it be an empty constructor or one that initializes with some default variables.
The problem is your constructor expects values which are not given by default.

CSpecial(int one,int two,int three,int four);
should change to
CSpecial(int one=1,int two=2,int three=3,int four=4);

or something along those lines.

The alternative is to have a constructor that takes no parameters: CSpecial::CSpecial() {}
and then have your overloaded constructor as you had it.

The point is the compiler has to be able to access a constructor that has some default data, whether it be an empty constructor or one that initializes with some default variables.


Sorry about the tripple post... I'm having difficulties replying to threads (connection keeps timing out) so I hit the button a couple of times (3 I guess).

[edited by - Stealth2000 on August 23, 2002 2:24:02 PM]
quote: Original post by Zorbfish
What''s is different from Horton''s example?

Horton''s pulled a fast one. He''s defaulted all parameters for Box, which has the effect of providing the following ctor''s:

Box(double, double, double);
Box(double, double);
Box(double); // conversion ctor!
Box(); // default ctor

This would be widely regarded as poor programming practice on at least a couple of counts. Firstly, defaulting member function parameters is poor form because it both obfuscates the intent, and can provide surprises when you derive from the class, since you can''t override the default and have it behave polymorphically (don''t worry if you don''t understand that, it doesn''t happen often). Secondly, he has a conversion ctor, which allows implicit conversion from double to type Box, which will allow code expecting a Box to compile when a double is passed. Implicit conversions can bite, so the default action should be to disallow them unless you specifically want them. Good C++ texts will explain all this to you.

I wouldn''t employ Horton to design Box classes for my team unless he cleaned his act up first.
Actually, the problem is not that you don't have a default constructor for CSpecial, but (as written in the error message) that CBase doesn't have a default constructor.

When you create a CSpecial object, a CBox object is created BEFORE CSpecial's constructor's body is executed. CSpecial's constructor doesn't specify HOW to create a CBox, and so the compiler tries to call CBox's default constructor. Since CBox doesn't have a default constructor, you get the error message.
The correct way to write constructors for inherited objects is by calling the parent class's constructor in the initialization list, like this:
CSpecial::CSpecial(int one, int two, int three, int four) : CBox(one, two, three){   m_four = four;}  

(in fact, a better way would be to put ALL the initializations in an initialization list, but this is just to illustrate the point)


[edited by - eyal on August 23, 2002 4:51:33 PM]

This topic is closed to new replies.

Advertisement