Confusion over inheritance

This is a discussion on Confusion over inheritance within the C++ Programming forums, part of the General Programming Boards category; Hi all, I have experiencing a couple of problems with a project that I am doing for school. Unfortunately in ...

  1. #1
    Registered User dalek's Avatar
    Join Date
    May 2003
    Posts
    135

    Confusion over inheritance

    Hi all,

    I have experiencing a couple of problems with a project that I am doing for school. Unfortunately in trying to write a cut down version of the code so I can explaing my problem, I have come across another issue that I cannot solve.

    Any ideas?

    Given the following code, I get this error:
    main.cpp(11): error C2243: 'type cast' : conversion from 'CFlower *' to 'CPlant *' exists, but is inaccessible
    Code:
    #ifndef CPLANT_H_
    #define CPLANT_H_
    
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    class CPlant
    {
    private:
    	char *plantName;
    
    public:
    	CPlant(char *);
    	~CPlant(void);
    	char* getPlantName(void);
    };
    
    #endif // CPLANT_H_
    Code:
    #include "CPlant.h"
    
    CPlant::CPlant(char* name)
    {
    	plantName = NULL;
    	plantName = new char[strlen(name) + 1];
    	strcpy(plantName, name);
    }
    
    CPlant::~CPlant(void)
    {
    	if (plantName)
    	{
    		delete [] plantName;
    		plantName = NULL;
    	}
    }
    	
    char * CPlant::getPlantName(void)
    {
    	return plantName;
    }
    Code:
    #ifndef CFLOWER_H_
    #define CFLOWER_H_
    
    #include <iostream>
    #include <cstring>
    #include "CPlant.h"
    
    using namespace std;
    
    
    class CFlower : CPlant
    {
    private:
    	char *flowerColor;
    
    public:
    	CFlower(char *, char *);
    	~CFlower(void);
    	char* getFlowerColor(void);
    };
    
    #endif // CFLOWER_H_
    Code:
    #include "CFlower.h"
    
    CFlower::CFlower(char *name, char *color) : CPlant(name)
    {
    	flowerColor = NULL;
    	flowerColor = new char [strlen(color) + 1];
    	strcpy(flowerColor, color);
    }
    
    CFlower::~CFlower(void)
    {
    	if (flowerColor)
    	{
    		delete [] flowerColor;
    		flowerColor = NULL;
    	}
    }
    
    char* CFlower::getFlowerColor(void)
    {
    	return flowerColor;
    }
    Code:
    #include <iostream>
    #include "CPlant.h"
    #include "CFlower.h"
    
    using namespace std;
    
    int main(void)
    {
    	CPlant *plant[2];
    
    	plant[0] = new CFlower("Rose", "Red");
    	plant[1] = new CFlower("Rose", "Yellow");
    
    
    	return 0;
    }

  2. #2
    Registered User
    Join Date
    May 2003
    Posts
    148
    In C++ private inheritance is default,try public
    Code:
    class CFlower : public CPlant
    {
    private:
    ...

  3. #3
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,786
    >>class CFlower : CPlant

    should be class CFlower : public CPlant


    Also, dont bother using char*....use std::string - i's easier and safer.

    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    class CPlant
    {
    private:
    	string plantName;
    public:
    	CPlant(const string&);
    	~CPlant(void);
    	const string& getPlantName(void) const;
    };
    
    
    CPlant::CPlant(const string& name): plantName(name)
    {
    }
    
    
    CPlant::~CPlant(void)
    {
    }
    
    const string& CPlant::getPlantName(void) const
    {
    	return plantName;
    }
    
    
    class CFlower : public CPlant
    {
    private:
    	string flowerColor;
    public:
    	CFlower(const string&,const string&);
    	~CFlower(void);
    	const string& getFlowerColor(void)const;
    };
    
    
    
    CFlower::CFlower(const string& name, const string& color)
    	 :CPlant(name),flowerColor(color)
    {
    }
    
    CFlower::~CFlower(void)
    {
    }
    
    const string& CFlower::getFlowerColor(void)const
    {
    	return flowerColor;
    }
    
    
    int main(void)
    {
    	CPlant *plant[2];
    	plant[0] = new CFlower("Rose", "Red");
    	plant[1] = new CFlower("Rose", "Yellow");
    	return 0;
    }
    ::EDIT:: Beaten to it!

  4. #4
    Registered User dalek's Avatar
    Join Date
    May 2003
    Posts
    135
    Goddam it! I can't believe I missed that. Your a legend. Thanks Wledge. :)

    Ok - now I can ask my real problem.. given the above code (and given that there is public inheritance with regards to CPlant) I would like to overload the << operator in the derived class CFlower.. as such
    Code:
    ostream& CFlower::operator<<(ostream &os)
    {
    	os << "The Flower Color: " << *flowerColor << endl;
    
    	return os;
    }
    Then, in the main function I need to be able to loop through the array of derived objects and using the overloading << operator output the details.
    Code:
        cout << *plant[0];
    But I get this error message:
    main.cpp(14): error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'CPlant' (or there is no acceptable conversion)
    Any ideas?

    [edit] : Thanks fordy, must have only been beaten by minutes ;)
    Good point regarding the string class, will make adjustments.
    Last edited by dalek; 06-22-2003 at 03:04 AM.

  5. #5
    Registered User dalek's Avatar
    Join Date
    May 2003
    Posts
    135
    I'm pretty convinced at this point that the problem is because when I am dereferencing the pointer to the subclass the compiler cannot determine the type of the class required, it is assuming that the class is of type CPlant, for which the << operator is not overloaded. I can't quite work out how to force it to treat the pointer as a pointer to a CFlower object..

  6. #6
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,786
    To overload << for your class you need to overload a function outside of your class

    ala;

    ostream& operator<<(ostream& out,const foo& f);

    But as it's outside your class, it cant normally access private or protected members, so you declare this function as a friend in your class declaration


    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    class foo
    {
    	string str;
    public:
    	foo(const string& str_):str(str_){}
    	friend ostream& operator<<(ostream&,const foo&);
    };
    
    ostream& operator<<(ostream& out,const foo& f)
    {
    	out << f.str;
    	return out;
    }
    
    int main(void)
    {
    	foo f("Hello World");
    	cout << f << endl;
    }

  7. #7
    Registered User
    Join Date
    Jun 2003
    Posts
    245
    Try this in your class:

    friend ostream &operator << (ostream &stream, CFlower flower);

    Then any output stream can be given a CFlower class.

    EDIT: Dang, beaten by Fordy.

  8. #8
    Registered User dalek's Avatar
    Join Date
    May 2003
    Posts
    135
    Thanks all. :)

    There was another problem that I have just solved. Could you let me know if you agree?

    When the CFlower class was instantiated and a pointer stored in the array of CPlant (the base class type), the compiler could not determine at run time, which object was being called. Therefore even if I had the correctly overloaded operator<< method in the subclass, it would always come up with the error:
    main.cpp(14): error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'CPlant' (or there is no acceptable conversion)
    because it couldn't find the operator<< in the base class that CFlower was derived from.

    It took me some time to realise that RTTI was not enabled by default in MSVC++ 7 but when I did the dynamic cast worked. My only adjustments to the code are what is here in the main function and to ensure that dynamic binding has been enabled in the base class. [edit]: and of course the operator<< code as suggested by you two lovely people :)
    Code:
    	CPlant *plant[2];
    
    	plant[0] = new CFlower("Rose", "Red");
    	plant[1] = new CFlower("Rose", "Yellow");
    	
    	CFlower *tmp;
    
    	tmp = dynamic_cast <CFlower *> (plant[0]);
    
    	cout << *tmp;
    
    	return 0;
    Cheers :)
    Last edited by dalek; 06-22-2003 at 07:13 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 06-08-2009, 03:03 PM
  2. Inheritance in c++
    By Non@pp in forum C++ Programming
    Replies: 7
    Last Post: 02-22-2006, 06:24 PM
  3. Multiple Inheritance - Size of Classes?
    By Zeusbwr in forum C++ Programming
    Replies: 10
    Last Post: 11-26-2004, 08:04 AM
  4. inheritance and performance
    By kuhnmi in forum C++ Programming
    Replies: 5
    Last Post: 08-04-2004, 12:46 PM
  5. Inheritance vs Composition
    By Panopticon in forum C++ Programming
    Replies: 11
    Last Post: 01-20-2003, 03:41 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21