Thread: calling the contructor again

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    28

    calling the contructor again

    hi Guys,

    i got a question...
    lets say i have a class "A" that can only be constructed with an int parameter

    like this:
    Code:
    A objA(1);
    how can i reinitialized objA?


    first attempt:
    Code:
    A objA(1);
    objA(2);
    but i get a compile error that the term doesn't evaluate to to 1 argument. am i missing parameters? ( there is nothing else named objA )


    second attempt:
    Code:
    A objA(1);
    objA.A(2);
    i get the error : 'function-style cast' : illegal as right side of '.' operator


    if i do this:
    Code:
    A objA(1);
    objA = A(2);
    against my will the deconstructor of the temporary object get called and the copied data members become invalid.


    i've tried this:
    Code:
    A objA(1);
    objA = A(2);
    
    A objNewA(2);
    objA = objNewA;
    but when objNewA goes out of scope it will get destructed.


    basicly i just want to call the constructor of an object again. do i have to use A by reference or something?
    can someone please explain?

  2. #2
    Weak. dra's Avatar
    Join Date
    Apr 2005
    Posts
    166
    Why is it necessary for you to call the constructor again? If you've got code in the constructor of your body, why not wrap it up in a public member function that way you can call it again if you need to...

    Code:
    class A
    {
    public:
    	A(int a){ init(a); };
    	void init(int a){ /*.....*/ };
    };
    otherwise, it seems placement new is what you're looking for if you really want the ability to call the constructor again.

    Can you invoke an instantiated object's class constructor explicity in C++? - Stack Overflow

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    28
    thanks,

    well basicly this object is in this case a data member of a class (by value).
    i prefer keeping things by value and i can see how you are right.

    i don't really want to drift off topic but that object is a winsock wrapper and according to the documentation they are basicly unusable after a connection is closed ( i ). this pattern doesn't make sense to me. that's why i thought about replacing the object. automatically doing that inside the wrapper object doesn't seem that clean because i would have to remember the previous settings ( and i was able to keep things minimal upto this point with it's only data member being the SOCKET handle )

    an annoying situation

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    against my will the deconstructor of the temporary object get called and the copied data members become invalid.
    Then you have a larger problem in the class, that its copy constructor and assignment operator are not implemented properly.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    28
    when i overload the assignment operator the destructor of the temporary object still gets called.

    if i change the data member of the assigning ( right hand ) object to a specific invalid value during the assignment and have the destructor check for this value before deallocating it works for the temporary object in this way:

    Code:
    A objA(1);
    
    objA = A(2);
    but it doesn't work in this case:

    Code:
    A objA(1);
    
    A objNewA(2);
    objA = objNewA;  // objNewA will have the invalid value
    from an assignment you would only expect a copy to be made. or is that something that i would then have to accept?

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    if i change the data member of the assigning ( right hand ) object to a specific invalid value during the assignment
    You must be doing something wrong. The right-hand value should not be modified by assigning. (There's a basic choice between doing a deep copy of stuff, or sharing stuff in an intelligent way - e.g through reference-counting.)

    You could post the real code for the class definition, the constructors, destructors and assignment operator to let people help you sort these things out.

    But you can also use a kind of reset() method, and then the constructor could also be implemented in terms of it. (The copying behaviour will still need to be fixed in one way or another.)
    Last edited by anon; 05-08-2009 at 02:35 PM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    28
    oh i'm not familiar implementing ref counting. this is the code i was talking about

    mySocket.h
    Code:
    #if !defined(_MYSOCKET_H)
    #define _MYSOCKET_H
    
    #include <string>
    #include <winsock2.h>
    #pragma comment (lib, "ws2_32.lib") // avoids manually specifying this lib file to the linker
    
    class mySocket
    {
    private:
      SOCKET _hSocket; // winsock handle
    public:  
      mySocket( const std::string& protocol )
      {
        // winsock data
        static const int winsock_ver_minimum = 2;
        WSADATA wsaData;
    
        // start winsock
        WSAStartup( MAKEWORD(winsock_ver_minimum,0), &wsaData);
        
        // acquire socket handle
        _hSocket = INVALID_SOCKET;
        if( protocol == "TCP" )
        { 
           _hSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); 
        }
        else if( protocol == "UDP" )
        {
          _hSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
        }
      }
    
      mySocket& operator=( mySocket& other )
      {
        
        // destroy old socket handle
        if( _hSocket != INVALID_SOCKET )
        {
          closesocket( _hSocket );
        }
        
        _hSocket = other._hSocket;       // copy other socket handle
        other._hSocket = INVALID_SOCKET; // prevent other from destroying socket handle
    
        return *this;                    // return this
        
      }
      
      // destroy socket
      ~mySocket()
      {
        if( _hSocket != INVALID_SOCKET )
        {
          closesocket( _hSocket );
        }
      }
    };
    
    #endif  //_MYSOCKET_H
    main.cpp
    Code:
    #include "mySocket.h"
    
    int main( int argc, char* argv[] )
    {
      mySocket objSocket( "TCP" );
      objSocket = mySocket( "TCP" );
    
      mySocket objSocket2( "TCP" );
      objSocket = objSocket2; // objSocket2::_hSocket will contain INVALID_SOCKET
    
      return 0;
    }
    any suggestions are welcome.
    Last edited by symbiote; 05-08-2009 at 04:18 PM. Reason: changed mySocket.cpp to mySocket.h

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    That's a pretty good example of "how to NOT write a class".

    What is the purpose of copying a socket class, by the way? What does it actually do? I don't mean what the code itself does, but why would you want to COPY an object in the first place... I'd say if both left and right part of the socket object is usable after a assignment operator, then you should forbid the assignment by making the operator private (which essentially prevents the object from being assigned).

    Your constructor also allows you to create an object that doesn't work - e.g. if you do not pass in TCP or UDP - _hSocket is set to "invalid". You may want to consider using an "open" member function to open the socket itself. That way, you can return an error.

    Or you could throw an exception if the constructor can't form a valid object.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    28
    yeah. i guess it's not the best example. i was planning on adding error checking afterwards.
    actually i don't want to make a copy because that would mean an other object with the same value is left dangling. the core issue is i just that i don't like it that sockets can't be used after losing a connection ( doesn't make sense to me, but if someone could give me a reasonable explanation then that would solve the problem aswell ).

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'm not sure which makes most sense when the connecction is lost:
    1. call a "reconnecct" (or "connect") member function.
    2. destroy the current object, and create a new one.
    3. throw an exception, then do 2.

    Obviously, if the connection is lost, you need to do something to make the socket object usable again - there is no doubt about that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Jan 2009
    Posts
    28
    thanks for the advice.
    i have added exceptions.
    i think i'll do what dra and matsp said ( destroy and create a new object ). keeps things simple and reflects the winsock documentation.

    Greetings,
    symbiote

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Stack issues when calling a COM library
    By notnot in forum C Programming
    Replies: 3
    Last Post: 06-01-2009, 02:12 AM
  2. calling functions within functions
    By edd1986 in forum C Programming
    Replies: 3
    Last Post: 03-29-2005, 03:35 AM
  3. calling default instead of argument constructor, why?!
    By cppn00b in forum C++ Programming
    Replies: 6
    Last Post: 01-30-2005, 04:24 AM
  4. calling conventions
    By Micko in forum C Programming
    Replies: 2
    Last Post: 07-18-2004, 09:13 AM
  5. Question on function syntax and calling function
    By cbrman in forum C Programming
    Replies: 10
    Last Post: 10-05-2003, 05:32 PM