user466534
user466534

Reputation:

question about getting value from class

consider following code

#include <iostream>
using namespace std;
class MyClass{
  int a;
  public:
    MyClass(int j) {a = j;}
    int geta(void) {return a;}
};

int main(void)
{
  MyClass ob = 99;              

  cout << ob.geta();
}

output of this code is 99 my question is following statement MyClass ob is declare object of class MyClass and is allowed such kind of declaration that object is equal some number?maybe more specific declaration would be MyClass ob(99) what do you think?

Upvotes: 0

Views: 95

Answers (4)

x13n
x13n

Reputation: 4163

You provided constructor taking an int. Without explicit keyword it can be called implicitly - like here. If you would write MyClass ob(99), you would call this constructor explicitely. There is no difference until you declare constructor as explicit. You would get compilation error when trying to assign an int to an object with explicit constructor.

EDIT: I checked - it is really using copy constructor too, as David and Alien01 said. It is just Visual Studio that doesn't follow the standard.

Upvotes: 3

The general answer has already been provided by others, including @x13n. I will try to provide a little more detailed explanation of what the code really means.

The syntax MyObject ob = anotherMyObject; is equivalent to MyObject obj( anotherMyObject );. The meaning is copy construct ob from the object anotherMyObject. The compiler will always match MyObject ob = ...; with a call to the copy constructor (usually MyObject( MyObject const &), but can also be MyObject( MyObject& ) if the user declares it as so).

In your particular code, the right hand side is not a MyObject, so it cannot be passed as an argument to the copy constructor and the compiler will try to convert that rhs into something that can be used with the copy constructor of MyObject applying the general rules. In your case, there is an implicit constructor that takes an int argument, and that can be used to create a temporary MyObject, so the compiler rewrites your code to be:

MyObject ob( MyObject( 99 ) );
//              ^^^  temporary created by the compiler to match the copy constructor

Note that this is not the same as MyObject ob(99), but a combination of the int and copy constructors, even if the overall effect is similar. If the constructor taking an integer was declared explicit, then the compiler could not use it to provide the conversion and the code would fail to compile.

In a comment to another answer @x13n points out that this is not a call to the copy constructor, as if you add a trace to that constructor, the trace will not be generated. That is a completely different issue, where the compiler is able to optimize away the copy by creating the temporary in exactly the same address that ob takes. There are two ways that this can be verified, both dependent on the fact that while the compiler can elide the copy it must adhere to the same restrictions. So we can make MyObject ob( MyObject(99) ) invalid in two ways, either disabling access to the copy constructor, or disabling the call to the constructor with a temporary:

class test1 {
   test1( test1 const & ) {} // make the copy constructor private
public:
   test1( int ) {}
};
class test2 {
public:
   test2( test2 & ) {} // make the copy constructor take a non-const reference 
                       // i.e. disable the use of temporaries
   test2( int ) {}
};
int main() {
   test1 t1 = 99; // copy constructor is private in this context
   test2 t2 = 99; // g++: no matching function call to test2::test2(test2)
                  // diagnostics will differ with other compilers
}

Upvotes: 1

anand
anand

Reputation: 11349

When you are creating an object like

MyClass ob =99 ;

You are basically calling constructor of the class.

Same holds good when object is created as

MyClass ob(99);

In this case also ,constructor of class is called.

Upvotes: 2

Mephane
Mephane

Reputation: 2022

This is the interesting part:

    MyClass(int j) {a = j;}

By default, a constructor with a single argument is implicit, which means the compiler automatically calls it wherever you want to assign an int where a MyClass is expected.

If you don't want this behaviour for your class, simply change the constructor to

    explicit MyClass(int j) {a = j;}

And the behaviour is gone, now you need to explicitly (hence the keyword) call the constructor every time. Note that the explicit keyword should only appear in the declaration in the class body, but not in an implementation outside of the body.

P.S.: This is, for example, how const char* automatically becomes a std::string when the latter is expected.

Upvotes: 2

Related Questions