Thread: Destructor called upon creation

  1. #1
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102

    Destructor called upon creation

    Hi...

    I've got a small problem. When I declare an instance of the class CWindow, its both - constructor and destructor are called.

    Declaration of the class:
    Code:
    class CWindow
    {
    public:
    	CWindow(char* pType, char *pCaption, int x, int y, int cx, int cy, HMENU hId, HWND hParent);
    	CWindow(HWND hWnd);
    	CWindow();
    	~CWindow();
    
    	friend class CMainApp;
    private:
    	HWND hwnd;
    	RECT rect;
    };
    Fuctions of CWindow:
    Code:
    CWindow::CWindow(char* pType, char* pCaption, int x, int y, int cx, int cy, HMENU hId, HWND hParent)
    {
    	hwnd = CreateWindowEx(NULL, pType, pCaption, WS_CHILD|WS_VISIBLE, x, y, cx, cy, hParent, hId, hinstance, NULL);
    	GetClientRect(hwnd, &rect);
    }
    
    CWindow::CWindow(HWND hWnd)
    {
    	hwnd = hWnd;
    	GetClientRect(hwnd, &rect);
    }
    
    CWindow::CWindow()
    {
    }
    
    CWindow::~CWindow()
    {
    	DestroyWindow(hwnd);
    }
    Use of the class:
    Code:
    CWindow questionStatic = CWindow("static", pQuestion, 30, 10, 200, 30, NULL, hwnd);
    The debugger shows that this line is executed twice. The first execution calls the constructor, the second calls the destructor. I must be missing something very obvious here, but can't find what.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You are creating a temporary object and then copying it to questionStatic. You probably want to write:
    Code:
    CWindow questionStatic("static", pQuestion, 30, 10, 200, 30, NULL, hwnd);
    That said, with compiler optimisations on, that temporary object would most likely be elided.
    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
    890
    You're creating a temporary object and then invoking its copy constructor. The temporary is then destructed. Just do this:

    CWindow questionStatic("static", ...);

  4. #4
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102
    I see... thanks for explaining, but then how would I create the object in a function of another class with questionStatic being a member of the class?

    Code:
    class CAnotherClass
    {
    public:
                void Show(HWND hwnd);
    private:
    	CWindow questionStatic;
    };
    Code:
    void CAnotherClass::Show(HWND hwnd)
    {
    	questionStatic = ...
    }
    Thanks for all your help again!

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    In that case you cannot avoid copying, unless CAnotherClass keeps a (smart) pointer to CWindow.
    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

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Quote Originally Posted by Overlord View Post
    I see... thanks for explaining, but then how would I create the object in a function of another class with questionStatic being a member of the class?

    Code:
    class CAnotherClass
    {
    public:
                void Show(HWND hwnd);
    private:
    	CWindow questionStatic;
    };
    Code:
    void CAnotherClass::Show(HWND hwnd)
    {
    	questionStatic = ...
    }
    Does it need to be a member? Why not just create it in CAnotherClass::Show()?

  7. #7
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102
    I'll need it in other class functions as well.

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Quote Originally Posted by Overlord View Post
    I'll need it in other class functions as well.
    Is it the same message everytime? If not, can you construct it once in the constructor, and then call setters (for the message text, etc) and display it in the other member functions?

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Looks like what you need is a "Create()" method that mirrors the current constructors functionality.

    gg

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Looks like what you need is a "Create()" method that mirrors the current constructors functionality.
    Yes, that might be a better option than storing a (smart) pointer if copying is a problem... which also implies that perhaps the copy constructor and copy assignment operator should be made private.

    EDIT:
    Perhaps that is the underlying problem: CWindow performs RAII by calling DestroyWindow(hwnd) in its destructor, but it does not properly handle copying by either performing a deep copy (which is perhaps not reasonable) or disabling copying. So perhaps CWindow should either perform RAII and be non-copyable, or not perform RAII and be copyable, or perform RAII and be copyable by means of reference counting.
    Last edited by laserlight; 04-21-2008 at 01:47 PM.
    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

  11. #11
    Registered User
    Join Date
    Jan 2006
    Location
    Latvia
    Posts
    102
    I'll try it with pointers first (I believe this will suite me).

    Thank you all for the valuable replies.

  12. #12
    Registered User
    Join Date
    Jan 2007
    Posts
    330
    You *can* avoid copying with an initializer list

    Code:
    class CAnotherClass
    {
    public:
                CAnotherClass();
    
                void Show(HWND hwnd);
    private:
    	CWindow questionStatic;
    };
    
    CAnothefrClass::CAnotherClass() : questionStatic("static", ...)
    {
    }

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You *can* avoid copying with an initializer list
    An initialisation list can only be used in a constructor. By the time Show() is called, questionStatic has already been instantiated.
    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

  14. #14
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by laserlight View Post
    An initialisation list can only be used in a constructor. By the time Show() is called, questionStatic has already been instantiated.
    Yeah but he has a point though. The CWindow could perhaps be initialised in the constructor instead, and only shown (made visible) in the Show function.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  15. #15
    Registered User
    Join Date
    Jan 2007
    Posts
    330
    Quote Originally Posted by iMalc View Post
    Yeah but he has a point though. The CWindow could perhaps be initialised in the constructor instead, and only shown (made visible) in the Show function.
    thats what i meant yeah, just fill the member in the constructor and the actual showing in Show

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 12-16-2008, 02:43 PM
  2. File creation date (in windows 98 and XP)
    By esbo in forum C Programming
    Replies: 12
    Last Post: 05-03-2006, 05:27 PM
  3. program not working...please look at this
    By JOlszewski in forum C Programming
    Replies: 3
    Last Post: 01-30-2006, 10:33 PM
  4. Dynamic Creation of an object
    By axr0284 in forum Windows Programming
    Replies: 3
    Last Post: 02-05-2005, 10:27 AM
  5. Newton + Einstein were wrong!
    By Jez in forum A Brief History of Cprogramming.com
    Replies: 64
    Last Post: 12-14-2004, 02:24 PM