c++pointers

How do you destroy an object in its constructor and return NULL


I am trying to write a cpp module that must check for proper initialization. It needs to be initialized with at least one non-NULL pointer. If not, it needs to delete itself and return NULL. The following program does seem to destroy the object, but it doesn't seem to return null.

What's going on here?

#include <iostream>

using namespace std;

class cmod {
public:
        cmod(int *p1=NULL, int *p2=NULL)
        {
                if( p1 == NULL && p2 == NULL){
                        delete(this);
                }
                else
                        cout << __func__ << ": Initialized" << endl;
                if(p1 != NULL)
                        cout << "*p1 = " << *p1 << endl;
                if(p2 !=NULL)
                        cout << "*p2 = " << *p2 << endl;
        }
        ~cmod()
        {
                cout << __func__ << ": Destroyed" << endl;
        }

};

int main()
{
        int a=10, b = 20;
        cmod *p = new cmod();
        if(p == NULL)
                cout << __func__ << ": Unable to initialize" << endl;
        cmod *p1 = new cmod(&a, &b);
}

The following is the output:

~cmod: Destroyed
cmod: Initialized
*p1 = 10
*p2 = 2

Why is the line Unable to initialize not printing?

UPDATE: After looking at all the answers, I came up with the following:

#include <iostream>

using namespace std;

class cmod {
private:
        int *l1,*l2;
        cmod()
        {
                throw std::runtime_error("Failed to construct object.   No arguments");
        }
        cmod(int *p1=NULL, int *p2=NULL)
        {
                if( p1 == NULL && p2 == NULL){
                        throw std::runtime_error("Failed to construct object. Both args NULL");
                }
                else
                        cout << __func__ << ": Initialized" << endl;
                if(p1 != NULL)
                        l1 = p1;
                if(p2 !=NULL)
                        l2 = p2;
        }
        ~cmod()
        {
                cout << __func__ << ": Destroyed" << endl;
        }
public:
        static cmod * initialize(int *p1=NULL, int *p2 = NULL)
        {
                if( p1 == NULL && p2 == NULL){
                        return NULL;
                }
                else
                        return new cmod(p1,p2);

        }
        void dump()
        {
                cout << __func__ << ": a = " << *l1 << endl;
                cout << __func__ << ": b = " << *l2 << endl;

        }
int main()
{
        int a=10, b = 20;
        cmod *p = cmod::initialize(NULL, NULL);
        if(p == NULL)
                cout << __func__ << ": Unable to initialize" << endl;
        cmod *p1 = cmod::initialize(&a, &b);
        if(p!=NULL)
                p->dump();
        if(p1!=NULL)
                p1->dump();
}

Is this a proper approach now?


Solution

  • If you want to validate the input before constructing an object, it will be better to use a static member function that does that instead of validating the input in the constructor. Also, make the constructor private to prevent accidental misuse.

    class cmod {
    
       public:
    
          static cmod* buildInstance(int *p1=NULL, int *p2=NULL)
          {
             if( p1 == NULL && p2 == NULL){
                return NULL;
             }
             else {
                return new cmd(p1, p2);
             }
          }
    
          ~cmod()
          {
             cout << __func__ << ": Destroyed" << endl;
          }
    
       private:
    
          cmod(int *p1, int *p2)
          {
             cout << __func__ << ": Initialized" << endl;
             if(p1 != NULL)
                cout << "*p1 = " << *p1 << endl;
             if(p2 !=NULL)
                cout << "*p2 = " << *p2 << endl;
          }
    
    };
    

    and then use it as:

    int main()
    {
       int a=10, b = 20;
       cmod *p = mod::buildInstance();
       if(p == NULL)
          cout << __func__ << ": Unable to initialize" << endl;
       cmod *p1 = cmod::buildInstance(&a, &b);
    }