Thread: constructor

  1. #1
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203

    Question constructor

    I have a doubt.
    1) Is it true that constructors do not have a return type?
    Proceed IFF true->
    2) In that case how can an explicit call be made?
    Code:
    class foo;
    int main(){
    foo a(4.76, 3);
    //written as
    foo a = foo(4.76, 3); //wouldn't this be returning a foo?
    }
    3) We type convert from user defined class to pre-defined / Primitive by:
    Code:
    class foo{
    private:
    //blah blah;
    public:
    float operator float(){
    //blah, blah;
    }
    };
    But how do we do the reverse?
    Code:
    foo(type);
    would not be correct as it is a constructor, and cannot return a value.
    Please help...

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    1) Is it true that constructors do not have a return type?
    Yes.

    2) In that case how can an explicit call be made?
    In your example, the foo object a is instantiated with a copy of a temporary foo object created by foo(4.76, 3).
    You may need to write a copy constructor, e.g.
    foo(const foo&);

    But then in your case it is much better to use the foo(4.76, 3) call immediately, obviously.

    But how do we do the reverse?
    Write a constructor that accepts an object of the desired type in its parameter.
    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
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    In a way, you could say that a constructor implicitely returns itself. Since it can't return anything else, the return type is never mentioned. Similar to how conversion operators don't have an explicit return type either.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    1)Everything I've ever read says constructors don't have a return type, but they do create an object which somehow gets stored in a variable name, so they sure act like they return an object.

    2)As laser light mentioned, this line:

    foo a = foo(4.76, 3);

    does some things behind the scenes that aren't apparent. First, it shows that a constructor acts like a static function: you can call the constructor using just the class name. Second, the segment:

    foo a

    does not call the default constructor, which would be the case in this line:

    foo a;

    Instead, the 'a' object is created using the unnamed object created by foo(4.76, 3). To create a foo object using another foo object, you need a constructor that takes a foo object as a parameter. Just as the compiler supplies a class with a default constructor, the compiler also supplies a class with what's called a default copy constructor. The default copy constructor is a constructor that has a class object as a parameter, and it copies each member of the parameter object to the object that calls the copy constructor. In your code, assigning an object to 'a' while it is being declared serves to call the copy constructor. For example, examine the output of this program:
    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Apple
    { 
    private:
    	string color;
    
    public:
    	Apple(string c)
    	{
    		color = c;
    	}
    
    	void show()
    	{
    		cout<<"My apple's color is: "<<color<<endl;
    	}
    
    	Apple(const Apple& a)  //copy constructor
    	{
    		cout<<endl
    		    <<"copy constructor called."
    		    <<endl;
    
    		color = a.color;
    	}
    };
    
    int main()
    {
    	Apple myApple("red");
    	myApple.show();
    
    	//Apple b; //ERROR--no default constructor
    
    	Apple a = Apple("green");
    	a.show();
    
    	return 0;
    }
    
    output:
    
    My apple's color is: red
    
    copy constructor called.
    My apple's color is: green
    3) We type convert from user defined class to pre-defined / Primitive by:
    Code:
    class foo
    {
    private:
    	//blah blah;
    
    public:
    	float operator float()
    	{
    		//blah, blah;
    	}
    };
    That's not quite right. When you overload a type conversion, you do not specify a return type:

    float operator float()

    The float return type is implicit, so it is not listed (the function should still have a return statement that returns a float).

    Code:
    But how do we do the reverse?
    
    foo(type);
    It doesn't make sense to convert a primitive type to a class object. For instance, what is the meaning of converting an int to a Dog object? If you want to do that, then you have to define what it means. To create objects of your class with an int, then as laserlight said, you need to define a constructor that takes an int parameter. For instance, in the Apple class, you could define a constructor like this:
    Code:
    Apple(int number)
    {
    	if(number < 10)
    		color = "red";
    	else
    		color = "green";
    }
    That allows you to write statements like this:

    Apple b(4);

    However, you still can't write statements like this:

    Apple b("red");
    b(4); //ERROR-term does not evaluate to a function
    Last edited by 7stud; 06-13-2005 at 03:00 PM.

  5. #5
    ... arjunajay's Avatar
    Join Date
    May 2005
    Posts
    203

    Exclamation example?

    Thanks.
    I never thoght about the copy constructor being involved.
    It doesn't make sense to convert a primitive type to a class object
    I saw a 'fuzzy' logic class which uses floating point numbers and uses both conversions in an article found in generation 5.com.
    Code:
    #include <iostream.h>
    #include <math.h>
    #include "fuzzy.h"
    
    void main() {
       fuzzy fz1 = 0.5,                   // 0.5
             fz2 = (fz1 | 0.4f) & 0.45f,  // 0.45//look below(1)
             fz3 = !fz2 | fz2,            // 0.55
             fz4 = !(fz1 - fz2);          // 0.95
       bool  bl5 = fz3.contained(fz2),    // false
             bl6 = fz2.contained(fz3);    // true
    
       cout << "Class 'fuzzy' logical operators:" << endl;
       cout << "fz1 = " << fz1 << endl
            << "fz2 = " << fz2 << endl
            << "fz3 = " << fz3 << endl
            << "fz4 = " << fz4 << endl;
       cout << endl;
       cout << "bl5 = " << ((bl5) ? "true" : "false") << endl
            << "bl6 = " << ((bl6) ? "true" : "false") << endl;
    }
    
    Judging from the comments I've put in, I think you can guess the output of the program! Nevertheless,
    you can see how easy it is to use the class. Just to reassure you, let us look at fz2 and fz3. fz2 is the
     result of ((0.5 OR 0.4) AND 0.45). Remember OR takes the maximum, so that equates to 0.5,
    and AND takes the minimum - therefore fz2 equals 0.45. On to fz3, that is (NOT(fz2) OR fz2) - the 
    NOT of fz2 is 1 - 0.45 = 0.55, which is bigger than 0.45. 
    The "contained" function returns 
    true iff A <= B. The class also has float type conversion routine, so you can use fuzzy and float synonymously 
    when pass parameters to functions(like cout::operator<<). You can download the code.....
    (1)here they mixed float and fuzzy variables in an expression, thus implicitly converting the float var to fuzzy type
    Last edited by arjunajay; 06-14-2005 at 05:15 AM. Reason: nothing?

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    here they mixed float and fuzzy variables in an expression, thus implicitly converting the float var to fuzzy type
    I don't think that is correct. It looks to me like they overloaded the operator | and the operator & for the fuzzy class. For example, in the Apple class, if I defined a float type conversion and a float were implicitly converted to type Apple in a statement like this:

    myApple = anApple | 0.5f;

    what would myApple1 | myApple2 mean? As far as I know, a type conversion operator is called:

    1) when you assign another type to your class type, e.g.

    myfuzzy = 0.5f;

    2) when you explicitly make a cast:

    myfuzzy = static_cast<fuzzy>(0.5f); //error see CornedBee's post below

    3) in a constructor e.g.:

    Apple(0.5f); //error see CornedBee's post below



    ((0.5 OR 0.4) AND 0.45). Remember OR takes the maximum, so that equates to 0.5,
    and AND takes the minimum - therefore fz2 equals 0.45.
    Where am I supposed to remember that from? What I remember is that a bitwise OR(|) only operates on integral types and the result is not the max of the two numbers. Instead, the result is an OR'ing of the columns of the numbers in binary format. For example:

    cout<< (4 | 2)<<endl;

    produces 6. That's because 4 in binary is 100 and 2 in binary is 10, and when you OR(|) them together, you get:

    100
    010 OR
    -----
    110

    and binary 110 is 6.
    Last edited by 7stud; 06-14-2005 at 04:30 PM.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    A type conversion operator is called when:

    1) you assign another type to your class type, e.g.

    myfuzzy = 0.5f;

    2) you explicitly make a cast:

    myfuzzy = static_cast<fuzzy>(0.5f);

    3) ??
    The other way round. A type conversion operator is used when:
    1) You explicitely cast your object to that type:
    float f = static_cast<float>(myobj);
    2) You implicitely cast your object to that type in various ways:
    float f = myobj;
    void f(float);
    f(myobj);

    A conversion constructor (a constructor that can be called with a single argument that is not of the same type as the constructor's class - that would be a copy constructor - and that is not marked as explicit) is used for explicit and implicit conversions from the parameter type.

    Where am I supposed to remember that from?
    From when you learned fuzzy logic. Though I agree, in this case it would be better to overload ||.

    But where are you supposed to remember from that << applied to a left-hand-side stream argument means write to stream?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    The other way round.
    Ahhh, thanks.

    You implicitely cast your object to that type in various ways:
    Thanks. I was adding the implicit contructor cast to my post while you were posting, but I got that one backwards too.

    Didn't know about the implict function parameter cast.

    From when you learned fuzzy logic
    Never heard of it.
    Last edited by 7stud; 06-14-2005 at 04:29 PM.

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 06-10-2008, 08:38 PM
  2. C++ have a constructor call another constructor
    By QuestionC in forum C++ Programming
    Replies: 4
    Last Post: 05-17-2007, 01:59 AM
  3. Replies: 3
    Last Post: 03-26-2006, 12:59 AM
  4. Need help in classes
    By LBY in forum C++ Programming
    Replies: 11
    Last Post: 11-26-2004, 04:50 AM
  5. Constructor with Parameter not Firing
    By BillBoeBaggins in forum Windows Programming
    Replies: 4
    Last Post: 08-26-2004, 02:17 PM