0
#include <string.h>
#include <iostream>
using namespace std;

class String
{
    public:
        /* Parameterized Constructor */
        String(const char* i_ac)
        {
            cout<<"Parameterized Constructor";
            if(i_ac)
            {
                data = new char [strlen(i_ac) + 1];
                strcpy(data,i_ac);
            }
            else
            {
                data = new char[1];
                *data = '\0';
            }
        }
        //Parametrized constructor ends.

        /*Copy Constructor */
        String ( String& objTemp )
        {
            cout<<"Copy Constructor";
            data = new char[strlen(objTemp.data) + 1];
            strcpy(data,objTemp.data); 
        }

        /*Overloaded Assignment Operator */
        String operator=(String& objTemp)
        {
            if(this == &objTemp)
            return objTemp;
            //Delete Existing data
            delete[] data;
            data = new char[strlen(objTemp.data)+ 1];
            strcpy(data,objTemp.data);
            return *this;
        }

        friend ostream& operator<<(ostream& out, String& s1);

    private :
        char* data;
};

ostream& operator<<(ostream& o1, String& s1)
{
    o1<<s1.data;
    return o1;
}

int main()
{
    String s1("Hello");
    cout<<"s1"<<s1;
    String s2 = s1;
    cout<<"\ns2"<<s2;
    String s3(); //doubt
    cout<<"\ns3"<<s3;
}

On calling String s3(), no constructor is called (I know since I print inside each constructor). However, printing s3 on the following line outputs a 1.

Why isn't a constructor called? How can I make sure one is called?

Trojan
  • 2,256
  • 28
  • 40
  • Not the reason for the error, but you really should be passing `const String&`. – juanchopanza Dec 25 '13 at 09:43
  • String s3(); is treated as a function declaration, I think. That's why no constructor is called. If you remove the () you'll end up with a call to the constructor that takes no arguments, which doesn't exist. – Einheri Dec 25 '13 at 09:49

2 Answers2

2

Just a note: do try clang, it has some really good diagnostics:

t.cpp:64:10: warning: empty parentheses interpreted as a function declaration [-Wvexing-parse]
String s3(); //doubt
         ^~
t.cpp:65:15: warning: address of function 's3' will always evaluate to 'true' [-Wbool-conversion]
cout<<"\ns3"<<s3;
~~~~          ^~
t.cpp:65:15: note: prefix with the address-of operator to silence this warning
cout<<"\ns3"<<s3;
              ^
              &
2 warnings generated.
Mat
  • 202,337
  • 40
  • 393
  • 406
2

Why isn't a constructor called? How can I make sure one is called?

This will not work, this does not call the empty ctor, it creates a local method.

String s3(); //doubt
cout<<"\ns3"<<s3;

To make this work, remove the () from String s3(); to become String s3;

String s3; // This is the correct form

(I think this is one of the most common mistakes when starting out with C++). But do note that this will trigger a linker error since you don't have defined an empty ctor. I guess you want to use your "Parameterized" ctor to act as the empty ctor as well based on the if/else condition in there. To achieve this you will have to give the argument i_ac a default value of 0 or NULL. Or if you are using C++11, use nullptr since NULL is considered an abomination.

Side notes:

However, printing s3 on the following line outputs a 1.

This will evaluate s3 to a bool, hence why you get the '1' outputted.

/*Copy Constructor */
String ( String& objTemp )

This should really be written as

/*Copy Constructor */
String ( const String& objTemp )

Same goes for

/*Overloaded Assignment Operator */
String operator=(String& objTemp)

// Add const
String operator=(const String& objTemp)
grenangen
  • 168
  • 2
  • 10