class A
{
public:
A(constclass B& a)
{
std::cout<<"class B is converted to A";
}
};
class B
{
int c;
public:
void get() const
{
c=10;
}
};
void function(const A& a)
{
std::cout<<"Value of a is " <<c1.getA();
}
int main(int argc, char* argv[])
{
B b; // line 1
function(b); //line 2
}
line 2 only works if the constructor for class A is A(constclass B& a) and ofcourse the function definition is void function(const A& a)
I am not able to understand the chain of events happening here. Can anyone of you explain?
When you define a constructor with only one parameter, which is the reference or value of a different class-object, you tell the compiler that implicit conversions are possible. This means that B can be A. (While A cannot necessarily be B, in this code.) Since the function calls a member function which is local to A, it cannot have const B& as parameter. But, because of the possibility to read B as A, B is allowed to be put into that function.
@Kylon.. Thanks.. What I am not able to understand is that why the A(B& a) is not able to the job that A(const class B& a) does? why does compiler throw error during compilationf for my former declaration?
The idea behind const objects is that they can't be changed.
To ensure this, there are a few rules:
- const objects can only have const functions called on them
- const objects can only be passed as const parameters
- const functions cannot change the state of 'this'
class B
{
public:
int foo;
};
class A
{
public:
A(B& b)
{
b.foo = 5; // since b is not const, this is perfectly acceptable
}
};
int main()
{
const B b; // a const B object
// the whole point of the const keyword is to guarantee 'b's state won't change. It is constant.
A a(b); // ERROR
}
This is an error because 'b' is const, and the A ctor would be changing it (destroying its const-ness).
I was more or less stating the same as you just did. The lower level fallacies seemed redundant and would over complicate things a lot. Also, +1 to forward declaration.
class B;
class A
{
public:
A(constclass B& a)
{
std::cout<<"class B is converted to A";
}
};
class B
{
int c;
public:
void get() const
{
c=10;
}
};
void function(A& a)
{
std::cout<<"Value of a is " <<c1.getA();
}
int main(int argc, char* argv[])
{
B b; // line 1
function(b); //line 2
}
#include "stdafx.h"
#include<iostream>
class B;
class A
{
public:
A(class B& a)
{
std::cout<<"class B is converted to A";
}
void print()
{
}
};
class B
{
int c;
public:
void get()
{
c=10;
}
};
void function(A& a)
{
std::cout<<"Value of a is ";
a.print();
}
int main(int argc, char* argv[])
{
B b;
function(b);
return 0;
}
Coder777, stop spreading disinformation. Only post what you know for sure. I know for sure, that you allows implicit conversion from B to A by adding a single-argumented constructor in A that takes a B. The only problem is that you mix up your qualifiers a bit. Class should not be used inside a parameter declaration. Since this is kind of a strange conversion, we must ensure that no strange things happen, by making the input (B&) a constant value. (const B&)
Since this discards qualifiers for A::print(), we will have to make A::print() a constant function by suffixing it with const. (This means it cannot change values, and it's thus safe to use it, even on B. Finally, we change the A&, the function parameter, to const A&. You should get this result (note that the forward declaration is omitted since it's not needed in this context):
#include<iostream>
class B
{
int c;
public:
void get()
{
c=10;
}
};
class A
{
public:
A(const B& a)
{
std::cout<<"class B is converted to A";
}
void print() const
{
}
};
void function(const A& a)
{
std::cout<<"Value of a is ";
a.print();
}
int main(int argc, char** argv)
{
B b;
function(b);
return 0;
}
#include<iostream>
class B
{
int c;
public:
void get()
{
c=10;
}
};
class A
{
public:
A(const B& a)
{
std::cout<<"class B is converted to A";
}
void print() const
{
}
};
void function(const A& a)
{
std::cout<<"Value of a is ";
a.print();
}
int main(int argc, char** argv)
{
B b;
function(b);
return 0;
}
class A
{
public:
A(int) { }
};
void c_func(const A& a) {} // a function that takes a const A
void nc_func(A& a) { } // a function that takes a non-const A
int main()
{
// here's an example of calling the above WITHOUT a temporary object:
A a(5);
c_func(a); // call it with our non-temporary 'A' object
// this is an example of calling it with an explicit temporary
c_func( A(5) ); // this creates a nameless, temporary A object, and passes it to the function
// the temporary object is destroyed as soon as c_func returns. It no longer exists
// this is an example of calling it with an implicit temporary
c_func( 5 ); // this is the exactly same as above "explicit" call. a temporary A object is created and passed
/*
The kicker is... these temporary objects are always const. Therefore the above all work because the
function takes a const A as a parameter. However nc_func takes a non-const A, so it doesn't work with temporaries
*/
nc_func( a ); // OK, 'a' is non temporary and non-const, so the call is OK
nc_func( A(5) ); // ERROR, the temporary object is const, and the function takes a non-const param!
nc_func( 5 ); // ERROR, for same reason as above
}
So the solution to your problem is:
1) make the function take a const reference instead of a nonconst reference (as Kyon illustrated)
or
2) don't use a temporary object.