c++ object constructor question

I have the following code

class Param{
    public:
    Param(int aa, int bb){
        a=aa;
        b=bb;
    }
int a,b;
};

void function(Param);
int main(){

   function(2,3);
    return 0;
}
void function(Param par){
    cout<<par.a;
}

, and when I run it, I get the following message error:

.../main.cpp|21|error: conversion from �int� to non-scalar type �Param� requested|

I know the problem is that function should have been called with an object from Param, but I was expecting that the constructor Param(int , int) would do the job.
What is wrong with my assumption, and how could I fix this problem?

thank you in advance!!
santiagorf

It might be if you'd actually called it. You're just feeding it 2,3 not Param(2,3).

Thanks Corona688 for your prompt replay, and in fact if I call as

function( Param(2,3))

I will have the desired result. However, what I'm trying to generate is the behavior of the code below taken from "Teach yourself in 21 days".

Though the code is a little long there are few steps that are important (in black).

In the main function there is a call to a method SetFirstName from the class Employee

 Edie.SetFirstName("Edythe");

that pases as parameter a constant character string, but SetFirstName only requires a constant string reference.
This problem is solved by the String constructor

String(const char *const);

that takes a constant character string and makes a string.

So, in my code I was expecting to have the constructor

Param(int aa, int bb) 

the same behavior as

String(const char *const);

, but there is something I don't see.

   class String
   {
      public:
         // constructors
         String();
          String(const char *const);
          String(const String &);
         ~String();

         // overloaded operators
         char & operator[](int offset);
         char operator[](int offset) const;
         String operator+(const String&);
         void operator+=(const String&);
         String & operator= (const String &);

         // General accessors
         int GetLen()const { return itsLen; }
         const char * GetString() const { return itsString; }
         // static int ConstructorCount;

      private:
         String (int);         // private constructor
         char * itsString;
         unsigned short itsLen;

   };

   // default constructor creates string of 0 bytes
   String::String()
   {
      itsString = new char[1];
      itsString[0] = '\0';
      itsLen=0;
      // cout << "\tDefault string constructor\n";
      // ConstructorCount++;
   }

   // private (helper) constructor, used only by
   // class methods for creating a new string of
   // required size.  Null filled.
   String::String(int len)
   {
      itsString = new char[len+1];
      for (int i = 0; i<=len; i++)
         itsString = '\0';
      itsLen=len;
      // cout << "\tString(int) constructor\n";
      // ConstructorCount++;
   }

   // Converts a character array to a String
   String::String(const char * const cString)
   {
      itsLen = strlen(cString);
      itsString = new char[itsLen+1];
      for (int i = 0; i<itsLen; i++)
         itsString = cString;
      itsString[itsLen]='\0';
      // cout << "\tString(char*) constructor\n";
      // ConstructorCount++;
   }

   // copy constructor
   String::String (const String & rhs)
   {
      itsLen=rhs.GetLen();
      itsString = new char[itsLen+1];
      for (int i = 0; i<itsLen;i++)
         itsString = rhs;
      itsString[itsLen] = '\0';
      // cout << "\tString(String&) constructor\n";
      // ConstructorCount++;
   }

   // destructor, frees allocated memory
   String::~String ()
   {
      delete [] itsString;
      itsLen = 0;
      // cout << "\tString destructor\n";
   }

   // operator equals, frees existing memory
   // then copies string and size
   String& String::operator=(const String & rhs)
   {
      if (this == &rhs)
         return *this;
      delete [] itsString;
      itsLen=rhs.GetLen();
      itsString = new char[itsLen+1];
      for (int i = 0; i<itsLen;i++)
         itsString = rhs;
      itsString[itsLen] = '\0';
      return *this;
      // cout << "\tString operator=\n";
   }

   //non constant offset operator, returns
   // reference to character so it can be
   // changed!
   char & String::operator[](int offset)
   {
      if (offset > itsLen)
         return itsString[itsLen-1];
      else
         return itsString[offset];
   }

   // constant offset operator for use
   // on const objects (see copy constructor!)
   char String::operator[](int offset) const
   {
      if (offset > itsLen)
         return itsString[itsLen-1];
      else
         return itsString[offset];
   }

   // creates a new string by adding current
   // string to rhs
   String String::operator+(const String& rhs)
   {
      int  totalLen = itsLen + rhs.GetLen();
      String temp(totalLen);
      int i, j;
      for (i = 0; i<itsLen; i++)
         temp = itsString;
      for (j = 0; j<rhs.GetLen(); j++, i++)
         temp = rhs[j];
      temp[totalLen]='\0';
      return temp;
   }

   // changes current string, returns nothing
   void String::operator+=(const String& rhs)
   {
      unsigned short rhsLen = rhs.GetLen();
      unsigned short totalLen = itsLen + rhsLen;
      String  temp(totalLen);
      for (int i = 0; i<itsLen; i++)
         temp = itsString;
      for (int j = 0; j<rhs.GetLen(); j++, i++)
         temp = rhs[i-itsLen];
      temp[totalLen]='\0';
      *this = temp;
   }

 // int String::ConstructorCount = 0;
   class Employee
   {

   public:
      Employee();
      Employee(char *, char *, char *, long);
      ~Employee();
      Employee(const Employee&);
      Employee & operator= (const Employee &);

      const String & GetFirstName() const
         { return itsFirstName; }
      const String & GetLastName() const { return itsLastName; }
      const String & GetAddress() const { return itsAddress; }
      long GetSalary() const { return itsSalary; }

      void SetFirstName(const String & fName)
          { itsFirstName = fName; }
      void SetLastName(const String & lName)
         { itsLastName = lName; }
      void SetAddress(const String & address)
           { itsAddress = address; }
      void SetSalary(long salary) { itsSalary = salary; }
   private:
      String    itsFirstName;
      String    itsLastName;
      String    itsAddress;
      long      itsSalary;
   };

   Employee::Employee():
      itsFirstName(""),
      itsLastName(""),
      itsAddress(""),
      itsSalary(0)
   {}

   Employee::Employee(char * firstName, char * lastName,
      char * address, long salary):
      itsFirstName(firstName),
      itsLastName(lastName),
      itsAddress(address),
      itsSalary(salary)
   {}

   Employee::Employee(const Employee & rhs):
      itsFirstName(rhs.GetFirstName()),
      itsLastName(rhs.GetLastName()),
      itsAddress(rhs.GetAddress()),
      itsSalary(rhs.GetSalary())
   {}

   Employee::~Employee() {}

   Employee & Employee::operator= (const Employee & rhs)
   {
      if (this == &rhs)
         return *this;

      itsFirstName = rhs.GetFirstName();
      itsLastName = rhs.GetLastName();
      itsAddress = rhs.GetAddress();
      itsSalary = rhs.GetSalary();

      return *this;
   }
   int main()
   {
      Employee Edie("Jane","Doe","1461 Shore Parkway", 20000);

      Edie.SetFirstName("Edythe");


     cout << Edie.GetFirstName().GetString();

    return 0;
}

I don't see any similarity in design or inheritance between what you're trying to do and and the example you quote... I don't think the constructor is what lets it do that, are you sure that's the complete code? No external operator functions? Also: You can't cast one value into two values.

The code is taken from:

http://newdata.box.sk/bx/c/htm/ch15.htm

see listing 15.1 and 15.2. Most of the code is exactly the same as the one I posted with the exception of the main function. According to the book -and I debugged it in order to verify it- this behavior is due to the constructor from String.

I stand corrected, then. You still can't cast one parameter into two parameters, though. It could take a single class that had two members.

A better way to handle this case would be to overload function itself -- make another function of the same name that does in fact take two integers.

This is known as implicit conversion and for constructors it works if it has a single argument only.

If you have multiple arguments and want to make use of the implicit conversion, then you need a constructor having default values.

Something like...

class Param{
public:
    Param(int a, int b = 0) : _a(a), _b(b) {}
int _a,_b;
};
void function(Param par)
{
   cout<<par.a;
}
int main(){

   function(2);
   return 0;
}