Thread: Classes Help!!!

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    167

    Classes Help!!!

    Code:
    class ParentClass
    {
    	public:
    		ParentClass(string str_inputfile)
    		{
    			// do stuff
    		}
    };
    Code:
    class ChildClass : public ParentClass
    {
    	public:
    		ChildClass(string inputstr)
    		{
    			// do stuff
    		}
    };
    This gives me the errors:

    Code:
    main.cpp:417: error: no matching function for call to ‘ParentClass::ParentClass()’
    main.cpp:345: note: candidates are: ParentClass::ParentClass(std::string)
    main.cpp:343: note:                 ParentClass::ParentClass(const ParentClass&)
    What does it mean by "no matching function call" ?

    So I have to redefine *every* function in a parent class to get inheritance working?? That's annoying

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    No. Rather, ParentClass does not have a default constructor. Therefore, all subclass constructors must invoke one of ParentClass' constructors in their initialisation lists, e.g.,
    Code:
    ChildClass(string inputstr) : ParentClass(inputstr)
    {
        // do stuff
    }
    By the way, you may wish to pass std::string objects by const reference in this case.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    Will this actually call the parent's constructor? The parent constructor is doing some stuff that I really don't want the child to be doing again hehe

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Yes, it does. The initializer list directly calls a constructor of the mentioned object.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    What kind of things does the base class do that you don't want the derived class doing? Maybe the base class constructor shouldn't do it either, or maybe it needs a default constructor?

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    Quote Originally Posted by Elysia View Post
    Yes, it does. The initializer list directly calls a constructor of the mentioned object.
    Hmm, I see.

    I guess I should modify it then. Thanks all =]

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    I changed some stuff around, and now I have this:

    Code:
    class GraphObj
    {
    	public:
    		GraphObj(const string inputstr)
    		{
    			line = inputstr;
    		}
    
    		//virtual ~GraphObj() = 0;
    
    		virtual void draw(Image& img) = 0;
    	private:
    		string line;
    };
    And

    Code:
    class Line : public GraphObj
    {
    	public:
    		Line(const string inputstr) : GraphObj(inputstr)
    		{
    			line = inputstr;
    		}
    
    		//~Line() : ~GraphObj()
    		//{
    		//}
    
    		void draw(Image& img)
    		{
    			// do stuff
    		}
    	private:
    		string line;
    };
    Two questions:

    If I want to use inheritance, do I have to have the stuff in bold, or is it done automatically for me? (So I can delete it and the "line" variable will still be created / initialized)

    Also, it gives me some warnings:

    Code:
    main.cpp:24: warning: ‘class GraphObj’ has virtual functions but non-virtual destructor
    main.cpp:37: warning: ‘class Line’ has virtual functions but non-virtual destructor
    I tried to add the destructor stuff in but I'm not sure if I'm doing it right (the stuff commented out), because it gives a bunch of nasty errors about linking...

    I don't want to write a destructor for every one of my subclasses, but do I *have* to do it if I want to get rid of the warning?
    Last edited by Paul22000; 05-26-2008 at 11:08 AM.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Absolutely delete it.

    The problem is that you need an implementation of a destructor, even if it's pure. Easier to not make it pure, since you have a pure function already. (The only reason to make a destructor pure is
    to make a class abstract when it has no natural pure functions.)
    Code:
    virtual ~GraphObj() {}
    You don't need to explicitly create a destructor in any of the derived classes.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    If I want to use inheritance, do I have to have the stuff in bold, or is it done automatically for me? (So I can delete it and the "line" variable will still be created / initialized)
    Yes, though line will not be accessible to the derived class since it is private.

    I tried to add it in but I'm not sure if I'm doing it right.
    You are correct to write:
    Code:
    virtual ~GraphObj() = 0;
    But you still need to implement the base class destructor since it will be invoked by the derived class destructor:
    Code:
    GraphObj::~GraphObj() {}
    The derived class destructor can be left out (since the compiler generated one will do). If you implement it, the syntax would be:
    Code:
    Line::~Line()
    {
        // ...
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    Quote Originally Posted by CornedBee View Post
    Absolutely delete it.

    The problem is that you need an implementation of a destructor, even if it's pure. Easier to not make it pure, since you have a pure function already. (The only reason to make a destructor pure is
    to make a class abstract when it has no natural pure functions.)
    Code:
    virtual ~GraphObj() {}
    You don't need to explicitly create a destructor in any of the derived classes.
    Aha!

    I commented it out and it gave an error since line was private, so I made it protected.

    And then the destructor stuff, so I have:

    Code:
    class GraphObj
    {
    	public:
    		GraphObj(const string inputstr)
    		{
    			line = inputstr;
    		}
    		virtual ~GraphObj() {};
    		virtual void draw(Image& img) = 0;
    	protected:
    		string line;
    };
    Code:
    class Line : public GraphObj
    {
    	public:
    		Line(const string inputstr) : GraphObj(inputstr)
    		{
    		}
    		void draw(Image& img)
    		{
    			// stuff
    		}
    };
    No compile errors or warnings!!

    Now, my constructor in Line is completely blank... Do I even need it? Looks odd...

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    Quote Originally Posted by laserlight View Post
    Yes, though line will not be accessible to the derived class since it is private.


    You are correct to write:
    Code:
    virtual ~GraphObj() = 0;
    But you still need to implement the base class destructor since it will be invoked by the derived class destructor:
    Code:
    GraphObj::~GraphObj() {}
    The derived class destructor can be left out (since the compiler generated one will do). If you implement it, the syntax would be:
    Code:
    Line::~Line()
    {
        // ...
    }
    What's the difference between doing:

    virtual ~GraphObj() {};

    or

    GraphObj::~GraphObj() {};

    in my base class?



    Edit: hmm, nevermind, it gives the warning again about non-virtual functions with the 2nd method

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Paul22000 View Post
    What's the difference between doing:
    Code:
    		virtual ~GraphObj() {}
    or
    Code:
    		GraphObj::~GraphObj() {}
    in my base class?
    The first can be put inline the actual class definition and the second is placed outside the definition, so called implementation. Other that that, there's nothing different about them.
    And btw, drop the ";" after definitions (even if they're inline in the class definition).

    Edit: hmm, nevermind, it gives the warning again about non-virtual functions with the 2nd method
    What warning is that again?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Apr 2008
    Posts
    167
    Quote Originally Posted by Elysia View Post
    The first can be put inline the actual class definition and the second is placed outside the definition, so called implementation. Other that that, there's nothing different about them.
    And btw, drop the ";" after definitions (even if they're inline in the class definition).


    What warning is that again?
    The virtual functions thing

    main.cpp:24: warning: ‘class GraphObj’ has virtual functions but non-virtual destructor
    main.cpp:37: warning: ‘class Line’ has virtual functions but non-virtual destructor

    Hmm, guess I'll just use the virtual destructor way heh. I never have to call it myself so whatever is easier hehe

    -----

    Which semicolon? After class definitions?

    class Blah
    {

    };

    If I remove it, it gives errors

    Code:
    main.cpp:271: error: multiple types in one declaration

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Are you aware of the purpose of virtual functions, especially virtual destructors?
    If you aren't doing anything special in the destructor, you can omit the virtual destructors and ignore the warnings, but as they say, if a class has virtual functions, then it is also recommended that they have a virtual destructor.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    What's the difference between doing:

    virtual ~GraphObj() {};

    or

    GraphObj::~GraphObj() {};

    in my base class?
    Well the difference is really minor.
    Code:
    class Graph {
       public:
       virtual ~Graph() { 
          // defined inside the class
       }
    };
    
    class Graph {
       public:
       virtual ~Graph();
    };
    
    Graph::~Graph() {
       // defined outside the class
    }
    I've heard that defining functions inside the class suggests inlining them to the compiler, but that shouldn't work much better than the inline keyword. I've typically treated class declarations as outlines of the implementation and rarely put the implementations in the class. This helps me separate implementation from the class design.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you Initialize all classes once with New?
    By peacerosetx in forum C++ Programming
    Replies: 12
    Last Post: 07-02-2008, 10:47 AM
  2. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  3. Exporting VC++ classes for use with VB
    By Helix in forum Windows Programming
    Replies: 2
    Last Post: 12-29-2003, 05:38 PM
  4. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM